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