cancel
Showing results for 
Search instead for 
Did you mean: 

Custom Data Type

califa198
Champ in-the-making
Champ in-the-making
Hello,

I wanna know if its possible to make a custom data type. i would like to make a new data type for properties in which i can put 2 text fields for 1 data type, is this possible? where can i find information regarding this? it should be a data type just like d:text or d:datetime.

Anything would be useful, thanks

califa
17 REPLIES 17

jbarmash
Champ in-the-making
Champ in-the-making
You could probably do this, but I think that would require some serious backend coding.  

I'd discourage you from doing this - you can achieve the same effect by either creating an association to a content type with two  text fields, or by storing the data as one text field, and creating a component generator that renders it as two fields to the user.  Here is information about Component Generator framework.
    http://wiki.alfresco.com/wiki/Component_Generator_Framework

In any case - here are the pages on Content Modeling:
http://wiki.alfresco.com/wiki/Category:Content_Modeling

iblanco
Confirmed Champ
Confirmed Champ
Buffff!

I am interested in representing prices or other kind of precise decimal values in Alfresco.

I defined a custom data type mapped to java.math.BigDecimal in order to do so. I use it when defining a custom model and I configure the property sheets in the web-client to show it.

But when I try to use it in the web client the following problem arises:


11:54:20,476 ERROR [org.alfresco.web.ui.common.Utils] A system error happened during the operation: Property type not recognised:
   type: {http://www.binovo.es/model/content/1.0}decimal
org.alfresco.error.AlfrescoRuntimeException: Property type not recognised:
   type: {http://www.binovo.es/model/content/1.0}decimal
        at org.alfresco.repo.domain.NodePropertyValue.makeValueType(NodePropertyValue.java:620)
        at org.alfresco.repo.domain.NodePropertyValue.<init>(NodePropertyValue.java:683)
        at org.alfresco.repo.node.db.hibernate.HibernateNodeDaoServiceImpl.makeNodePropertyValue(HibernateNodeDaoServiceImpl.java:3905)
        at org.alfresco.repo.node.db.hibernate.HibernateNodeDaoServiceImpl.addValueToPersistedProperties(HibernateNodeDaoServiceImpl.java:3866)
        at org.alfresco.repo.node.db.hibernate.HibernateNodeDaoServiceImpl.addNodePropertyImpl(HibernateNodeDaoServiceImpl.java:1122)
        at org.alfresco.repo.node.db.hibernate.HibernateNodeDaoServiceImpl.addNodeProperties(HibernateNodeDaoServiceImpl.java:1176)
        at sun.reflect.GeneratedMethodAccessor700.invoke(Unknown Source)
(…)

At first I thougth it could be a problem with the component generator used for the UI, being it a new type it can't guess which one to use. So i explicitly configured the property so that it would be shown with TextFieldGenerator. But it didn't work.

In a second glance I noticed tha the error is thrown by org.alfresco.repo.domain.NodePropertyValue.makeValueType. This class seems to be related to the serialization of the properties in order to persist in the database.

To sum up this means that adding a new type is a really, really, really low level thing in Alfresco, so sadly jbarmash is completely right.

I'm going to use a double for now and in the midterm i might develop a custom component generator that eliminates the reamining decimals from the text input and that rounds the output value to the requested decimal numbers for the edition view.

It seems strange though that Alfresco hasn't this kind of data type available, or at least the component generator to "simulate it". Is there a good reason for this ?

billerby
Champ on-the-rise
Champ on-the-rise
I also gave up on this, when noticing some core classes seemed to be involved. My solution is to store it as cents/pennies in a long instead and use a converter for the gui-presentation.

iblanco
Confirmed Champ
Confirmed Champ
billerby could you please explain your solution a bit more extensively.
It would be a great help if you could show us some code also.

Thanks.

billerby
Champ on-the-rise
Champ on-the-rise
But of course  Smiley Very Happy

First in my model.xml file I declared my price property as of type d:long:

            <property name="ac:resursPris">
               <type>d:long</type>
               <mandatory>false</mandatory>
            </property>

In my web-client-config-custom.xml, when defning the propertySheet:

<show-property name="ac:resursPris" display-label-id="ac_smotModel.typ.ac_resurs.ac_resursPris" converter="PriceConverter"/>

My converter class: (We will not need decimals in our gui)

package com.acando.alfresco.web.resurs;

import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import javax.faces.convert.Converter;
import javax.faces.convert.ConverterException;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

public class PriceConverter implements Converter {
   
   private static Log log = LogFactory.getLog(PriceConverter.class);

      /**
       * <p>The standard converter id for this converter.</p>
       */
   public static final String CONVERTER_ID = "PriceConverter";

   public Object getAsObject(FacesContext context, UIComponent component,
         String value) throws ConverterException {

      if (value == null){
         return value;
      }
      
      value = value.trim();
      Long convertedValue = new Long(value);
      if (log.isDebugEnabled()){
         log.debug("multiplicerar "+value+" kronor med 100 för att få priset i ören, returnerar sedan för lagring");
      }

      return convertedValue*100;
   }

   public String getAsString(FacesContext context, UIComponent component,
         Object value) throws ConverterException {
      
      Long longValue = (Long)value;
      if (log.isDebugEnabled()){
         log.debug("dividerar "+value+" öre med 100 för att få priset i kronor, formaterar sedan och returnerar till gui.");
      }
      if (value == null){
         return "";
      }
      // first lets divide the cents with 100 to get the amount in SEK with decimals
      double convertedValue = longValue / 100;
      
      // decimals should not be visible in gui, lets remove them.
      int intMoney = (int)convertedValue;
      return String.valueOf(intMoney);
   }

}


Ok, last we need to make jsf aware of the converter, lets declare it in our faces-config-custom.xml

   <converter>
      <converter-id>PriceConverter</converter-id>
      <converter-class>com.acando.alfresco.web.resurs.PriceConverter</converter-class>
   </converter>



Regards
/Erik

iblanco
Confirmed Champ
Confirmed Champ
Thanks very much Erik.

I do need the decimals but I think that it will be quite easy to adapt your code for managing a couple of decimals. By the way, do you know if there is any way to pass a paramater to a converter ? That would allow to use a common converter for all kind of decimal representations just by saying how many decimals there are.

Thanks very much.

billerby
Champ on-the-rise
Champ on-the-rise
iblanco,

It seems that you can provide properties by defing them in faces-config, found an example:

<converter>
<converter-id>numberConverter</converter-id>
<converter-class>br.com.softcomex.components.gui.presentation.converters.NumberConverter</converter-class>
<property>
<property-name>maxFractionDigitsMask</property-name>
<property-class>java.lang.Integer</property-class>
</property>
</converter>

See full example at: http://www.theserverside.com/discussions/thread.tss?thread_id=45341

Good Luck
/Erik

billerby
Champ on-the-rise
Champ on-the-rise
iblanco,

It seems that you can provide properties by defing them in faces-config, found an example:

<converter>
<converter-id>numberConverter</converter-id>
<converter-class>br.com.softcomex.components.gui.presentation.converters.NumberConverter</converter-class>
<property>
<property-name>maxFractionDigitsMask</property-name>
<property-class>java.lang.Integer</property-class>
</property>
</converter>

iblanco
Confirmed Champ
Confirmed Champ
Thanks very much, I'll check it.