Anonymous avatar Anonymous committed 22ad46e

initial files

Comments (0)

Files changed (8)

+Copyright (c) 2011, Atlassian Pty Ltd
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
+
+    * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
+    * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the
+      documentation and/or other materials provided with the distribution.
+    * Neither the name of Atlassian nor the names of its contributors may be used to endorse or promote products derived from this software without
+      specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+DAMAGE.
+This tutorial shows you how to create a simple Custom Field that can store an amount of money.
+
+You can find the entire tutorial at: 
+
+https://developer.atlassian.com/display/JIRADEV/Plugin+Tutorial+-+Creating+a+Custom+Field+in+JIRA

src/main/java/com/example/plugins/tutorial/jira/customfields/MoneyCustomField.java

+package com.example.plugins.tutorial.jira.customfields;
+
+import com.atlassian.jira.issue.customfields.impl.AbstractSingleFieldType;
+import com.atlassian.jira.issue.customfields.impl.FieldValidationException;
+import com.atlassian.jira.issue.customfields.manager.GenericConfigManager;
+import com.atlassian.jira.issue.customfields.persistence.CustomFieldValuePersister;
+import com.atlassian.jira.issue.customfields.persistence.PersistenceFieldType;
+import com.atlassian.jira.util.NotNull;
+
+import java.math.BigDecimal;
+
+public class MoneyCustomField extends AbstractSingleFieldType<BigDecimal>
+{
+    public MoneyCustomField(CustomFieldValuePersister customFieldValuePersister, GenericConfigManager genericConfigManager) {
+        super(customFieldValuePersister, genericConfigManager);
+    }
+    @Override
+    public String getStringFromSingularObject(final BigDecimal singularObject)
+    {
+        if (singularObject == null)
+            return null;
+        else
+            return singularObject.toString();
+    }
+
+    @Override
+    public BigDecimal getSingularObjectFromString(final String string)
+            throws FieldValidationException
+    {
+        if (string == null)
+            return null;
+        try
+        {
+            final BigDecimal decimal = new BigDecimal(string);
+            // Check that we don't have too many decimal places
+            if (decimal.scale() > 2)
+            {
+                throw new FieldValidationException(
+                        "Maximum of 2 decimal places are allowed.");
+            }
+            return decimal.setScale(2);
+        }
+        catch (NumberFormatException ex)
+        {
+            throw new FieldValidationException("Not a valid number.");
+        }
+    }
+
+    @Override
+    protected PersistenceFieldType getDatabaseType()
+    {
+        return PersistenceFieldType.TYPE_LIMITED_TEXT;
+    }
+
+    @Override
+    protected BigDecimal getObjectFromDbValue(@NotNull final Object databaseValue)
+            throws FieldValidationException
+    {
+        return getSingularObjectFromString((String) databaseValue);
+    }
+
+    @Override
+    protected Object getDbValueFromObject(final BigDecimal customFieldObject)
+    {
+        return getStringFromSingularObject(customFieldObject);
+    }
+
+
+
+}

src/main/resources/atlassian-plugin.properties

+#
+#Wed Nov 09 15:11:00 EST 2011
+money-custom-field.description=Stores a money amount
+money-custom-field.name=Money Custom Field

src/main/resources/atlassian-plugin.xml

+<?xml version="1.0" encoding="UTF-8"?>
+
+<atlassian-plugin key="${project.groupId}.${project.artifactId}" name="${project.name}" plugins-version="2">
+  <plugin-info>
+    <description>${project.description}</description>
+    <version>${project.version}</version>
+    <vendor name="${project.organization.name}" url="${project.organization.url}"/>
+  </plugin-info>
+  <customfield-type name="Money Custom Field" i18n-name-key="money-custom-field.name" key="money-custom-field" class="com.example.plugins.tutorial.jira.customfields.MoneyCustomField">
+    <description key="money-custom-field.description">The Money Custom Field Plugin</description>
+    <resource name="view" type="velocity" location="/templates/customfields/money-custom-field/view.vm"/>
+    <resource name="edit" type="velocity" location="/templates/customfields/money-custom-field/edit.vm"/>
+  </customfield-type>
+  <resource type="i18n" name="i18n" location="atlassian-plugin"/>
+</atlassian-plugin>

src/main/resources/templates/customfields/money-custom-field/edit.vm

+#customControlHeader ($action $customField.id $customField.name $fieldLayoutItem.required $displayParameters $auiparams)
+<input class="text" id="$customField.id" name="$customField.id" type="text" value="$textutils.htmlEncode($!value)" />
+#customControlFooter ($action $customField.id $fieldLayoutItem.fieldDescription $displayParameters $auiparams)

src/main/resources/templates/customfields/money-custom-field/view.vm

+#if ($value)
+    $$value
+#end

src/test/java/com/example/plugins/tutorial/jira/customfields/MoneyCustomFieldTest.java

+package com.example.plugins.tutorial.jira.customfields;
+
+import com.atlassian.jira.issue.customfields.impl.FieldValidationException;
+import org.junit.Test;
+
+import java.math.BigDecimal;
+
+import static junit.framework.TestCase.assertEquals;
+import static junit.framework.TestCase.fail;
+
+public class MoneyCustomFieldTest {
+
+    @Test
+    public void testGetDbValueFromObject() throws Exception
+    {
+        MoneyCustomField moneyCustomField = new MoneyCustomField(null, null);
+        assertEquals("1", moneyCustomField.getDbValueFromObject(new BigDecimal(1)));
+        assertEquals("1.02", moneyCustomField.getDbValueFromObject(new BigDecimal("1.02")));
+        assertEquals("0.02", moneyCustomField.getDbValueFromObject(new BigDecimal("0.02")));
+    }
+
+    @Test
+    public void testGetStringFromSingularObject() throws Exception
+    {
+        MoneyCustomField moneyCustomField = new MoneyCustomField(null, null);
+        assertEquals("1", moneyCustomField.getStringFromSingularObject(new BigDecimal(1)));
+        assertEquals("1.02", moneyCustomField.getStringFromSingularObject(new BigDecimal("1.02")));
+        assertEquals("0.02", moneyCustomField.getStringFromSingularObject(new BigDecimal("0.02")));
+    }
+
+    @Test
+    public void testGetSingularObjectFromString() throws Exception
+    {
+        MoneyCustomField moneyCustomField = new MoneyCustomField(null, null);
+        assertEquals("3.00", moneyCustomField.getSingularObjectFromString("3").toString());
+        assertEquals("3.03", moneyCustomField.getSingularObjectFromString("3.03").toString());
+        assertEquals("3.20", moneyCustomField.getSingularObjectFromString("3.2").toString());
+        // Now test the errors:
+        try
+        {
+            moneyCustomField.getSingularObjectFromString("3 dollars");
+            fail("Validation should have failed.");
+        }
+        catch (FieldValidationException ex)
+        {
+            assertEquals("Not a valid number.", ex.getMessage());
+        }
+        try
+        {
+            moneyCustomField.getSingularObjectFromString("3.203");
+            fail("Validation should have failed.");
+        }
+        catch (FieldValidationException ex)
+        {
+            assertEquals("Maximum of 2 decimal places are allowed.", ex.getMessage());
+        }
+    }
+
+}
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.