001    /*
002     * Copyright (C) 2003-2009 eXo Platform SAS.
003     *
004     * This is free software; you can redistribute it and/or modify it
005     * under the terms of the GNU Lesser General Public License as
006     * published by the Free Software Foundation; either version 2.1 of
007     * the License, or (at your option) any later version.
008     *
009     * This software is distributed in the hope that it will be useful,
010     * but WITHOUT ANY WARRANTY; without even the implied warranty of
011     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
012     * Lesser General Public License for more details.
013     *
014     * You should have received a copy of the GNU Lesser General Public
015     * License along with this software; if not, write to the Free
016     * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
017     * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
018     */
019    package org.crsh.jcr;
020    
021    import javax.jcr.Node;
022    import javax.jcr.Property;
023    import javax.jcr.RepositoryException;
024    import java.io.InputStream;
025    import java.math.BigDecimal;
026    import java.math.BigInteger;
027    import java.util.*;
028    
029    /**
030     * @author <a href="mailto:julien.viet@exoplatform.com">Julien Viet</a>
031     * @version $Revision$
032     */
033    public enum PropertyType {
034    
035      PATH(javax.jcr.PropertyType.PATH){
036        @Override
037        public Object getValue(Property property) throws RepositoryException {
038          return property.getString();
039        }
040        @Override
041        public Property set(Node node, String name, Object value) throws RepositoryException {
042          if (value instanceof String) {
043            return node.setProperty(name, (String)value);
044          } else {
045            return null;
046          }
047        }
048        @Override
049        protected Collection<Class<?>> getCanonicalTypes() {
050          return Collections.emptySet();
051        }
052      },
053    
054      STRING(javax.jcr.PropertyType.STRING){
055        @Override
056        public Object getValue(Property property) throws RepositoryException {
057          return property.getString();
058        }
059        @Override
060        public Property set(Node node, String name, Object value) throws RepositoryException {
061          if (value instanceof String) {
062            return node.setProperty(name, (String)value);
063          } else if (value instanceof Character) {
064            return node.setProperty(name, Character.toString((Character)value));
065          } else {
066            return null;
067          }
068        }
069        @Override
070        protected Collection<Class<?>> getCanonicalTypes() {
071          return Arrays.<Class<?>>asList(String.class,Character.class);
072        }
073      },
074    
075      LONG(javax.jcr.PropertyType.LONG) {
076        @Override
077        public Object getValue(Property property) throws RepositoryException {
078          return property.getLong();
079        }
080        @Override
081        public Property set(Node node, String name, Object value) throws RepositoryException {
082          if (value instanceof Long) {
083            return node.setProperty(name, (Long)value);
084          } else if (value instanceof Integer) {
085            return node.setProperty(name, (Integer)value);
086          } else if (value instanceof Byte) {
087            return node.setProperty(name, (Byte)value);
088          } else if (value instanceof BigInteger) {
089            BigInteger biValue = (BigInteger)value;
090            return node.setProperty(name, biValue.longValue());
091          } else {
092            return null;
093          }
094        }
095        @Override
096        protected Collection<Class<?>> getCanonicalTypes() {
097          return Arrays.<Class<?>>asList(Long.class,Integer.class,Byte.class,BigInteger.class);
098        }
099      },
100    
101      DOUBLE(javax.jcr.PropertyType.DOUBLE) {
102        @Override
103        public Object getValue(Property property) throws RepositoryException {
104          return property.getDouble();
105        }
106        @Override
107        public Property set(Node node, String name, Object value) throws RepositoryException {
108          if (value instanceof Double) {
109            return node.setProperty(name, (Double)value);
110          }  else if (value instanceof Float) {
111            return node.setProperty(name, (Float)value);
112          } else if (value instanceof BigDecimal) {
113            BigDecimal bdValue = (BigDecimal)value;
114            return node.setProperty(name, bdValue.doubleValue());
115          } else {
116            return null;
117          }
118        }
119        @Override
120        protected Collection<Class<?>> getCanonicalTypes() {
121          return Arrays.<Class<?>>asList(Double.class,Float.class,BigDecimal.class);
122        }
123      },
124    
125      BOOLEAN(javax.jcr.PropertyType.BOOLEAN) {
126        @Override
127        public Object getValue(Property property) throws RepositoryException {
128          return property.getBoolean();
129        }
130        @Override
131        public Property set(Node node, String name, Object value) throws RepositoryException {
132          if (value instanceof Boolean) {
133            return node.setProperty(name, (Boolean)value);
134          } else {
135            return null;
136          }
137        }
138        @Override
139        protected Collection<Class<?>> getCanonicalTypes() {
140          return Arrays.<Class<?>>asList(Boolean.class);
141        }
142      },
143    
144      DATE(javax.jcr.PropertyType.DATE) {
145        @Override
146        public Object getValue(Property property) throws RepositoryException {
147          return property.getDate();
148        }
149        @Override
150        public Property set(Node node, String name, Object value) throws RepositoryException {
151          if (value instanceof Calendar) {
152            return node.setProperty(name, (Calendar)value);
153          } else {
154            return null;
155          }
156        }
157        @Override
158        protected Collection<Class<?>> getCanonicalTypes() {
159          return Arrays.<Class<?>>asList(Calendar.class);
160        }
161      },
162    
163      BINARY(javax.jcr.PropertyType.BINARY) {
164        @Override
165        public Object getValue(Property property) throws RepositoryException {
166          return property.getStream();
167        }
168        @Override
169        public Property set(Node node, String name, Object value) throws RepositoryException {
170          if (value instanceof InputStream) {
171            return node.setProperty(name, (InputStream)value);
172          } else {
173            return null;
174          }
175        }
176        @Override
177        protected Collection<Class<?>> getCanonicalTypes() {
178          return Arrays.<Class<?>>asList(InputStream.class);
179        }
180      },
181    
182      REFERENCE(javax.jcr.PropertyType.REFERENCE) {
183        @Override
184        public Object getValue(Property property) throws RepositoryException {
185          return property.getNode();
186        }
187        @Override
188        public Property set(Node node, String name, Object value) throws RepositoryException {
189          if (value instanceof Node) {
190            return node.setProperty(name, (Node)value);
191          } else {
192            return null;
193          }
194        }
195        @Override
196        protected Collection<Class<?>> getCanonicalTypes() {
197          return Arrays.<Class<?>>asList(Node.class);
198        }
199      };
200    
201      /** . */
202      private static final PropertyType[] all = new PropertyType[20]; // 20 should be enough
203    
204      /** . */
205      private static final Map<Class<?>, PropertyType> canonicalMapping = new HashMap<Class<?>, PropertyType>();
206    
207      static  {
208        for (PropertyType type : PropertyType.values())
209        {
210          all[type.value] = type;
211          for (Class<?> canonicalType : type.getCanonicalTypes())
212          {
213            canonicalMapping.put(canonicalType, type);
214          }
215        }
216      }
217    
218      public static PropertyType fromCanonicalType(Class<?> canonicalType)
219      {
220        for (Class<?> currentType = canonicalType;currentType != null;currentType = currentType.getSuperclass()) {
221          PropertyType type = canonicalMapping.get(currentType);
222          if (type != null) {
223            return type;
224          }
225        }
226    
227        //
228        return null;
229      }
230    
231      public static PropertyType fromValue(int v)
232      {
233        PropertyType type = null;
234        if (v >= 0 && v < all.length)
235        {
236          type = all[v];
237        }
238    
239        //
240        if (type == null)
241        {
242          throw new IllegalArgumentException("JCR Property type " + v + " not handled yet");
243        }
244        else
245        {
246          return type;
247        }
248      }
249    
250      /** . */
251      private final int value;
252    
253      PropertyType(int value) {
254        this.value = value;
255      }
256    
257      public int getValue() {
258        return value;
259      }
260    
261      public abstract Object getValue(Property property) throws RepositoryException;
262    
263      public abstract Property set(Node node, String name, Object value) throws RepositoryException;
264    
265      protected abstract Collection<Class<?>> getCanonicalTypes();
266    }