001 package org.trails.io;
002
003 import org.apache.commons.logging.Log;
004 import org.apache.commons.logging.LogFactory;
005 import org.apache.hivemind.ApplicationRuntimeException;
006 import org.apache.tapestry.services.DataSqueezer;
007 import org.apache.tapestry.util.io.SqueezeAdaptor;
008 import org.trails.util.Utils;
009 import org.trails.descriptor.DescriptorService;
010 import org.trails.descriptor.IClassDescriptor;
011 import org.trails.engine.encoders.abbreviator.EntityNameAbbreviator;
012 import org.trails.persistence.PersistenceService;
013 import org.trails.builder.BuilderDirector;
014 import org.trails.exception.TrailsRuntimeException;
015
016 import java.io.Serializable;
017
018 /**
019 * This class is a Trails adaptation of Tapernate's EntitySqueezerFilter Squeezes persistent entities
020 */
021 public class EntitySqueezerStrategy implements SqueezeFilter, SqueezeAdaptor
022 {
023 private static final Log LOG = LogFactory.getLog(EntitySqueezerStrategy.class);
024
025 String delimiter;
026 String prefix;
027
028 private DescriptorService descriptorService;
029
030 private PersistenceService persistenceService;
031
032 private EntityNameAbbreviator entityNameAbbreviator;
033 private boolean shouldAbbreviate = false;
034
035 private BuilderDirector builderDirector;
036
037 public String getPrefix()
038 {
039 return prefix;
040 }
041
042 public Class getDataClass()
043 {
044 return Squeezable.class;
045 }
046
047 public String squeeze(DataSqueezer dataSqueezer, Object o)
048 {
049 return squeeze(o, dataSqueezer);
050 }
051
052 public Object unsqueeze(DataSqueezer dataSqueezer, String s)
053 {
054 return unsqueeze(s, dataSqueezer);
055 }
056
057 public String squeeze(Object data, DataSqueezer next)
058 {
059
060 if (data != null)
061 {
062 IClassDescriptor classDescriptor = descriptorService.getClassDescriptor(data.getClass());
063 if (classDescriptor != null)
064 {
065 Serializable id = persistenceService.getIdentifier(data, classDescriptor);
066
067 if (LOG.isDebugEnabled())
068 {
069 LOG.debug("squeezing entity: " + data.toString());
070 }
071
072 if (id == null)
073 {
074 return prefix + entityNameAbbreviator.abbreviate(classDescriptor.getType());
075 }
076
077 // Serializable version = (Serializable) persistenceService.getVersion(data, classDescriptor);
078 return prefix + abbreviate(classDescriptor.getType()) + delimiter + next.squeeze(id);
079 }
080 }
081 return next.squeeze(data);
082 }
083
084 public String[] squeeze(Object[] objects, DataSqueezer next)
085 {
086 final String[] squeezed = new String[objects.length];
087 for (int i = 0; i < squeezed.length; i++)
088 {
089 squeezed[i] = squeeze(objects[i], next);
090 }
091 return squeezed;
092 }
093
094 public Object unsqueeze(String string, DataSqueezer next)
095 {
096 if (string.startsWith(prefix))
097 {
098 final String squeezed = string.substring(prefix.length());
099 final int delimiterNdx = squeezed.indexOf(delimiter);
100
101 final String entityName;
102 final Serializable id;
103
104 if (delimiterNdx > 0)
105 {
106 entityName = squeezed.substring(0, delimiterNdx);
107 id = (Serializable) next.unsqueeze(squeezed.substring(delimiterNdx + delimiter.length()));
108 } else
109 {
110 entityName = squeezed;
111 id = null;
112 }
113
114 final Class<?> clazz = (Class<?>) unabbreviate(entityName);
115
116 if (LOG.isDebugEnabled())
117 {
118 LOG.debug("unsqueezing entity: " + clazz.getName() + " : " + id);
119 }
120
121 if (id != null)
122 {
123 return persistenceService.loadInstance(clazz, id);
124 } else
125 {
126 try
127 {
128 return builderDirector.createNewInstance(clazz);
129 } catch (TrailsRuntimeException e)
130 {
131 throw new ApplicationRuntimeException("decode-failure: unable to unsqueeze entity", e);
132 }
133 }
134 } else
135 {
136 return next.unsqueeze(string);
137 }
138 }
139
140 public Object[] unsqueeze(String[] strings, DataSqueezer next)
141 {
142 final Object[] unsqueezed = new Object[strings.length];
143 for (int i = 0; i < unsqueezed.length; i++)
144 {
145 unsqueezed[i] = unsqueeze(strings[i], next);
146 }
147 return unsqueezed;
148 }
149
150 public void setDelimiter(String delimiter)
151 {
152 this.delimiter = delimiter;
153 }
154
155 public void setPrefix(String prefix)
156 {
157 this.prefix = prefix;
158 }
159
160 public void setDescriptorService(DescriptorService descriptorService)
161 {
162 this.descriptorService = descriptorService;
163 }
164
165 public void setPersistenceService(PersistenceService persistenceService)
166 {
167 this.persistenceService = persistenceService;
168 }
169
170 public void setEntityNameAbbreviator(EntityNameAbbreviator entityNameAbbreviator)
171 {
172 this.entityNameAbbreviator = entityNameAbbreviator;
173 shouldAbbreviate = entityNameAbbreviator != null;
174 }
175
176 public void setBuilderDirector(BuilderDirector builderDirector)
177 {
178 this.builderDirector = builderDirector;
179 }
180
181 private String abbreviate(Class clazz)
182 {
183 return shouldAbbreviate ? entityNameAbbreviator.abbreviate(clazz) : clazz.getName();
184 }
185
186 private Class unabbreviate(String abbreviation)
187 {
188 return shouldAbbreviate ? entityNameAbbreviator.unabbreviate(abbreviation) : Utils.classForName(abbreviation);
189 }
190 }