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.*;
022 import java.io.InputStream;
023 import java.math.BigDecimal;
024 import java.math.BigInteger;
025 import java.util.*;
026
027 /**
028 * @author <a href="mailto:julien.viet@exoplatform.com">Julien Viet</a>
029 * @version $Revision$
030 */
031 public enum PropertyType {
032
033 PATH(javax.jcr.PropertyType.PATH){
034 @Override
035 public Object unwrap(Value value) throws RepositoryException {
036 return value.getString();
037 }
038 @Override
039 protected Value wrap(ValueFactory factory, Object value) {
040 if (value instanceof String) {
041 return factory.createValue((String)value);
042 } else {
043 return null;
044 }
045 }
046 @Override
047 protected Collection<Class<?>> getCanonicalTypes() {
048 return Collections.emptySet();
049 }
050 },
051
052 STRING(javax.jcr.PropertyType.STRING){
053 @Override
054 public Object unwrap(Value value) throws RepositoryException {
055 return value.getString();
056 }
057 @Override
058 protected Value wrap(ValueFactory factory, Object value) {
059 if (value instanceof String) {
060 return factory.createValue((String) value);
061 } else if (value instanceof Character) {
062 return factory.createValue(Character.toString((Character) value));
063 } else {
064 return null;
065 }
066 }
067 @Override
068 protected Collection<Class<?>> getCanonicalTypes() {
069 return Arrays.<Class<?>>asList(String.class,Character.class);
070 }
071 },
072
073 LONG(javax.jcr.PropertyType.LONG) {
074 @Override
075 public Object unwrap(Value value) throws RepositoryException {
076 return value.getLong();
077 }
078 @Override
079 protected Value wrap(ValueFactory factory, Object value) {
080 if (value instanceof Long) {
081 return factory.createValue((Long) value);
082 } else if (value instanceof Integer) {
083 return factory.createValue((Integer) value);
084 } else if (value instanceof Byte) {
085 return factory.createValue((Byte) value);
086 } else if (value instanceof BigInteger) {
087 BigInteger biValue = (BigInteger)value;
088 return factory.createValue(biValue.longValue());
089 } else {
090 return null;
091 }
092 }
093 @Override
094 protected Collection<Class<?>> getCanonicalTypes() {
095 return Arrays.<Class<?>>asList(Long.class,Integer.class,Byte.class,BigInteger.class);
096 }
097 },
098
099 DOUBLE(javax.jcr.PropertyType.DOUBLE) {
100 @Override
101 public Object unwrap(Value value) throws RepositoryException {
102 return value.getDouble();
103 }
104 @Override
105 protected Value wrap(ValueFactory factory, Object value) {
106 if (value instanceof Double) {
107 return factory.createValue((Double) value);
108 } else if (value instanceof Float) {
109 return factory.createValue((Float) value);
110 } else if (value instanceof BigDecimal) {
111 BigDecimal bdValue = (BigDecimal)value;
112 return factory.createValue(bdValue.doubleValue());
113 } else {
114 return null;
115 }
116 }
117 @Override
118 protected Collection<Class<?>> getCanonicalTypes() {
119 return Arrays.<Class<?>>asList(Double.class,Float.class,BigDecimal.class);
120 }
121 },
122
123 BOOLEAN(javax.jcr.PropertyType.BOOLEAN) {
124 @Override
125 public Object unwrap(Value value) throws RepositoryException {
126 return value.getBoolean();
127 }
128 @Override
129 protected Value wrap(ValueFactory factory, Object value) {
130 if (value instanceof Boolean) {
131 return factory.createValue((Boolean) value);
132 } else {
133 return null;
134 }
135 }
136 @Override
137 protected Collection<Class<?>> getCanonicalTypes() {
138 return Arrays.<Class<?>>asList(Boolean.class);
139 }
140 },
141
142 DATE(javax.jcr.PropertyType.DATE) {
143 @Override
144 public Object unwrap(Value value) throws RepositoryException {
145 return value.getDate();
146 }
147 @Override
148 protected Value wrap(ValueFactory factory, Object value) {
149 if (value instanceof Calendar) {
150 return factory.createValue((Calendar) value);
151 } else {
152 return null;
153 }
154 }
155 @Override
156 protected Collection<Class<?>> getCanonicalTypes() {
157 return Arrays.<Class<?>>asList(Calendar.class);
158 }
159 },
160
161 BINARY(javax.jcr.PropertyType.BINARY) {
162 @Override
163 public Object unwrap(Value value) throws RepositoryException {
164 return value.getStream();
165 }
166 @Override
167 protected Value wrap(ValueFactory factory, Object value) {
168 if (value instanceof InputStream) {
169 return factory.createValue((InputStream) value);
170 } else {
171 return null;
172 }
173 }
174 @Override
175 protected Collection<Class<?>> getCanonicalTypes() {
176 return Arrays.<Class<?>>asList(InputStream.class);
177 }
178 },
179
180 REFERENCE(javax.jcr.PropertyType.REFERENCE) {
181 @Override
182 public Object unwrap(Value value) throws RepositoryException {
183 throw new AssertionError("It should not be called");
184 }
185 @Override
186 protected Value wrap(ValueFactory factory, Object value) throws RepositoryException {
187 if (value instanceof Node) {
188 return factory.createValue((Node)value);
189 } else {
190 return null;
191 }
192 }
193 @Override
194 protected Collection<Class<?>> getCanonicalTypes() {
195 return Arrays.<Class<?>>asList(Node.class);
196 }
197 };
198
199 /** . */
200 private static final PropertyType[] all = new PropertyType[20]; // 20 should be enough
201
202 /** . */
203 private static final Map<Class<?>, PropertyType> canonicalMapping = new HashMap<Class<?>, PropertyType>();
204
205 static {
206 for (PropertyType type : PropertyType.values())
207 {
208 all[type.value] = type;
209 for (Class<?> canonicalType : type.getCanonicalTypes())
210 {
211 canonicalMapping.put(canonicalType, type);
212 }
213 }
214 }
215
216 public static PropertyType fromCanonicalType(Class<?> canonicalType)
217 {
218 for (Class<?> currentType = canonicalType;currentType != null;currentType = currentType.getSuperclass()) {
219 PropertyType type = canonicalMapping.get(currentType);
220 if (type != null) {
221 return type;
222 }
223 }
224
225 //
226 return null;
227 }
228
229 public static PropertyType fromValue(int v)
230 {
231 PropertyType type = null;
232 if (v >= 0 && v < all.length)
233 {
234 type = all[v];
235 }
236
237 //
238 if (type == null)
239 {
240 throw new IllegalArgumentException("JCR Property type " + v + " not handled yet");
241 }
242 else
243 {
244 return type;
245 }
246 }
247
248 /** . */
249 private final int value;
250
251 PropertyType(int value) {
252 this.value = value;
253 }
254
255 public int getValue() {
256 return value;
257 }
258
259 public Object get(Property property) throws RepositoryException {
260 if (this == REFERENCE) {
261 return property.getNode();
262 } else {
263 Value value;
264 if (property.getDefinition().isMultiple()) {
265 Value[] values = property.getValues();
266 value = values.length > 0 ? values[0] : null;
267 } else {
268 value = property.getValue();
269 }
270 return value != null ? unwrap(value) : null;
271 }
272 }
273
274 public final Property set(Node node, String name, Object value) throws RepositoryException {
275 Value v = wrap(node.getSession().getValueFactory(), value);
276 if (v != null) {
277 try {
278 return node.setProperty(name, v);
279 } catch (ValueFormatException e) {
280 return node.setProperty(name, new Value[]{v});
281 }
282 }
283 return null;
284 }
285
286 protected abstract Object unwrap(Value value) throws RepositoryException;
287
288 protected abstract Value wrap(ValueFactory factory, Object value) throws RepositoryException;
289
290 protected abstract Collection<Class<?>> getCanonicalTypes();
291 }