001/* 002 * (C) Copyright 2006-2011 Nuxeo SA (http://nuxeo.com/) and others. 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 * 016 * Contributors: 017 * Nuxeo - initial API and implementation 018 * 019 * $Id$ 020 */ 021 022package org.nuxeo.common.xmap; 023 024import java.io.File; 025import java.net.MalformedURLException; 026import java.net.URL; 027import java.text.DateFormat; 028import java.text.ParseException; 029import java.util.Date; 030import java.util.Hashtable; 031import java.util.Map; 032 033import org.apache.commons.logging.Log; 034import org.apache.commons.logging.LogFactory; 035import org.w3c.dom.Node; 036 037/** 038 * Value factories are used to decode values from XML strings. 039 * <p> 040 * To register a new factory for a given XMap instance use the method {@link XMap#setValueFactory(Class, XValueFactory)}. 041 * 042 * @author <a href="mailto:bs@nuxeo.com">Bogdan Stefanescu</a> 043 */ 044public abstract class XValueFactory { 045 046 private static final Log log = LogFactory.getLog(XValueFactory.class); 047 048 static final Map<Class<?>, XValueFactory> defaultFactories = new Hashtable<Class<?>, XValueFactory>(); 049 050 public abstract Object deserialize(Context context, String value); 051 052 public abstract String serialize(Context context, Object value); 053 054 public final Object getElementValue(Context context, Node element, boolean trim) { 055 String text = element.getTextContent(); 056 return deserialize(context, trim ? text.trim() : text); 057 } 058 059 public final Object getAttributeValue(Context context, Node element, String name) { 060 Node at = element.getAttributes().getNamedItem(name); 061 return at != null ? deserialize(context, at.getNodeValue()) : null; 062 } 063 064 public static void addFactory(Class klass, XValueFactory factory) { 065 defaultFactories.put(klass, factory); 066 } 067 068 public static XValueFactory getFactory(Class type) { 069 return defaultFactories.get(type); 070 } 071 072 public static Object getValue(Context context, Class klass, String value) { 073 XValueFactory factory = defaultFactories.get(klass); 074 if (factory == null) { 075 return null; 076 } 077 return factory.deserialize(context, value); 078 } 079 080 public static final XValueFactory STRING = new XValueFactory() { 081 @Override 082 public Object deserialize(Context context, String value) { 083 return value; 084 } 085 086 @Override 087 public String serialize(Context context, Object value) { 088 return value.toString(); 089 } 090 }; 091 092 public static final XValueFactory INTEGER = new XValueFactory() { 093 @Override 094 public Object deserialize(Context context, String value) { 095 return Integer.valueOf(value); 096 } 097 098 @Override 099 public String serialize(Context context, Object value) { 100 return value.toString(); 101 } 102 }; 103 104 public static final XValueFactory LONG = new XValueFactory() { 105 @Override 106 public Object deserialize(Context context, String value) { 107 return Long.valueOf(value); 108 } 109 110 @Override 111 public String serialize(Context context, Object value) { 112 return value.toString(); 113 } 114 }; 115 116 public static final XValueFactory DOUBLE = new XValueFactory() { 117 @Override 118 public Object deserialize(Context context, String value) { 119 return Double.valueOf(value); 120 } 121 122 @Override 123 public String serialize(Context context, Object value) { 124 return value.toString(); 125 } 126 }; 127 128 public static final XValueFactory FLOAT = new XValueFactory() { 129 @Override 130 public Object deserialize(Context context, String value) { 131 return Float.valueOf(value); 132 } 133 134 @Override 135 public String serialize(Context context, Object value) { 136 return value.toString(); 137 } 138 }; 139 140 public static final XValueFactory BOOLEAN = new XValueFactory() { 141 @Override 142 public Object deserialize(Context context, String value) { 143 return Boolean.valueOf(value); 144 } 145 146 @Override 147 public String serialize(Context context, Object value) { 148 return value.toString(); 149 } 150 }; 151 152 public static final XValueFactory DATE = new XValueFactory() { 153 private final DateFormat df = DateFormat.getDateInstance(); 154 155 @Override 156 public Object deserialize(Context context, String value) { 157 try { 158 return df.parse(value); 159 } catch (ParseException e) { 160 return null; 161 } 162 } 163 164 @Override 165 public String serialize(Context context, Object value) { 166 Date date = (Date) value; 167 return df.format(date); 168 } 169 }; 170 171 public static final XValueFactory FILE = new XValueFactory() { 172 @Override 173 public Object deserialize(Context context, String value) { 174 return new File(value); 175 } 176 177 @Override 178 public String serialize(Context context, Object value) { 179 File file = (File) value; 180 return file.getName(); 181 } 182 }; 183 184 public static final XValueFactory URL = new XValueFactory() { 185 @Override 186 public Object deserialize(Context context, String value) { 187 try { 188 return new URL(value); 189 } catch (MalformedURLException e) { 190 return null; 191 } 192 } 193 194 @Override 195 public String serialize(Context context, Object value) { 196 return value.toString(); 197 } 198 }; 199 200 public static final XValueFactory CLASS = new XValueFactory() { 201 @Override 202 public Object deserialize(Context context, String value) { 203 try { 204 return context.loadClass(value); 205 } catch (ClassNotFoundException e) { 206 log.error("Cannot load class: " + value, e); 207 return null; 208 } 209 } 210 211 @Override 212 public String serialize(Context context, Object value) { 213 Class<?> clazz = (Class<?>) value; 214 return clazz.getName(); 215 } 216 }; 217 218 public static final XValueFactory RESOURCE = new XValueFactory() { 219 @Override 220 public Object deserialize(Context context, String value) { 221 return new Resource(context.getResource(value)); 222 } 223 224 @Override 225 public String serialize(Context context, Object value) { 226 return value.toString(); 227 } 228 }; 229 230 static { 231 addFactory(String.class, STRING); 232 addFactory(Integer.class, INTEGER); 233 addFactory(Long.class, LONG); 234 addFactory(Double.class, DOUBLE); 235 addFactory(Date.class, DATE); 236 addFactory(Boolean.class, BOOLEAN); 237 addFactory(File.class, FILE); 238 addFactory(URL.class, URL); 239 240 addFactory(int.class, INTEGER); 241 addFactory(long.class, LONG); 242 addFactory(double.class, DOUBLE); 243 addFactory(float.class, FLOAT); 244 addFactory(boolean.class, BOOLEAN); 245 246 addFactory(Class.class, CLASS); 247 addFactory(Resource.class, RESOURCE); 248 } 249 250}