PageRenderTime 27ms CodeModel.GetById 19ms RepoModel.GetById 1ms app.codeStats 0ms

/branches/1_4_3/src/org/rapla/entities/dynamictype/internal/DynamicTypeImpl.java

http://rapla.googlecode.com/
Java | 350 lines | 287 code | 42 blank | 21 comment | 63 complexity | 3ce9388c3f44fabaffc224f3cb26dab1 MD5 | raw file
Possible License(s): GPL-2.0, BSD-3-Clause, CPL-1.0, LGPL-2.0, AGPL-1.0
  1. /*--------------------------------------------------------------------------*
  2. | Copyright (C) 2006 Christopher Kohlhaas |
  3. | |
  4. | This program is free software; you can redistribute it and/or modify |
  5. | it under the terms of the GNU General Public License as published by the |
  6. | Free Software Foundation. A copy of the license has been included with |
  7. | these distribution in the COPYING file, if not go to www.fsf.org |
  8. | |
  9. | As a special exception, you are granted the permissions to link this |
  10. | program with every library, which license fulfills the Open Source |
  11. | Definition as published by the Open Source Initiative (OSI). |
  12. *--------------------------------------------------------------------------*/
  13. package org.rapla.entities.dynamictype.internal;
  14. import java.util.ArrayList;
  15. import java.util.Collection;
  16. import java.util.HashMap;
  17. import java.util.Iterator;
  18. import java.util.Locale;
  19. import org.rapla.components.util.Tools;
  20. import org.rapla.entities.EntityNotFoundException;
  21. import org.rapla.entities.IllegalAnnotationException;
  22. import org.rapla.entities.MultiLanguageName;
  23. import org.rapla.entities.Named;
  24. import org.rapla.entities.RaplaType;
  25. import org.rapla.entities.dynamictype.Attribute;
  26. import org.rapla.entities.dynamictype.Classification;
  27. import org.rapla.entities.dynamictype.ClassificationFilter;
  28. import org.rapla.entities.dynamictype.DynamicType;
  29. import org.rapla.entities.storage.EntityResolver;
  30. import org.rapla.entities.storage.Mementable;
  31. import org.rapla.entities.storage.RefEntity;
  32. import org.rapla.entities.storage.internal.SimpleEntity;
  33. public class DynamicTypeImpl extends SimpleEntity implements DynamicType,Named,Mementable,java.io.Serializable
  34. {
  35. // Don't forget to increase the serialVersionUID when you change the fields
  36. private static final long serialVersionUID = 2;
  37. // added an attribute array for performance reasons
  38. transient private boolean attributeArrayUpToDate = false;
  39. transient Attribute[] attributes;
  40. MultiLanguageName name = new MultiLanguageName();
  41. String elementKey = "";
  42. HashMap annotations = new HashMap();
  43. public DynamicTypeImpl() {
  44. }
  45. public void resolveEntities( EntityResolver resolver) throws EntityNotFoundException {
  46. super.resolveEntities( resolver);
  47. attributeArrayUpToDate = false;
  48. }
  49. public RaplaType getRaplaType() {return TYPE;}
  50. public Classification newClassification() {
  51. if ( !isPersistant()) {
  52. throw new IllegalStateException("You can only create Classifications from a persistant Version of DynamicType");
  53. }
  54. final ClassificationImpl classification = new ClassificationImpl(this);
  55. // Array could not be up todate
  56. final Attribute[] attributes2 = getAttributes();
  57. for ( Attribute att: attributes2)
  58. {
  59. final Object defaultValue = att.defaultValue();
  60. if ( defaultValue != null)
  61. {
  62. classification.setValue(att, defaultValue);
  63. }
  64. }
  65. return classification;
  66. }
  67. public Classification newClassification(Classification original) {
  68. if ( !isPersistant()) {
  69. throw new IllegalStateException("You can only create Classifications from a persistant Version of DynamicType");
  70. }
  71. final ClassificationImpl newClassification = (ClassificationImpl) newClassification();
  72. {
  73. Attribute[] attributes = original.getAttributes();
  74. for (int i=0;i<attributes.length;i++) {
  75. Attribute originalAttribute = attributes[i];
  76. String attributeKey = originalAttribute.getKey();
  77. Attribute newAttribute = newClassification.getAttribute( attributeKey );
  78. Object originalValue = original.getValue( attributeKey );
  79. if ( newAttribute != null && originalValue != null && newAttribute.getType().equals( originalAttribute.getType()) ) {
  80. newClassification.setValue( newAttribute, newAttribute.convertValue( originalValue ));
  81. }
  82. }
  83. return newClassification;
  84. }
  85. };
  86. public ClassificationFilter newClassificationFilter() {
  87. if ( !isPersistant()) {
  88. throw new IllegalStateException("You can only create ClassificationFilters from a persistant Version of DynamicType");
  89. }
  90. return new ClassificationFilterImpl(this);
  91. }
  92. public MultiLanguageName getName() {
  93. return name;
  94. }
  95. public void setReadOnly(boolean enable) {
  96. super.setReadOnly( enable );
  97. name.setReadOnly( enable );
  98. }
  99. public String getName(Locale locale) {
  100. return name.getName(locale.getLanguage());
  101. }
  102. public String getAnnotation(String key) {
  103. ParsedAnnotation parsedAnnotation =(ParsedAnnotation) annotations.get(key);
  104. if ( parsedAnnotation != null) {
  105. return parsedAnnotation.getExternalRepresentation(this);
  106. } else {
  107. return null;
  108. }
  109. }
  110. public boolean isRefering(RefEntity entity) {
  111. Attribute[] attributes = getAttributes();
  112. for ( int i=0;i<attributes.length;i++)
  113. {
  114. RefEntity attribute = (RefEntity)attributes[i];
  115. if ( attribute.isRefering( entity))
  116. {
  117. return true;
  118. }
  119. }
  120. return super.isRefering(entity);
  121. }
  122. public String getAnnotation(String key, String defaultValue) {
  123. String annotation = getAnnotation( key );
  124. return annotation != null ? annotation : defaultValue;
  125. }
  126. public void setAnnotation(String key,String annotation) throws IllegalAnnotationException {
  127. checkWritable();
  128. if (annotation == null) {
  129. annotations.remove(key);
  130. return;
  131. }
  132. annotations.put(key,new ParsedAnnotation(annotation, this));
  133. }
  134. public String[] getAnnotationKeys() {
  135. return (String[]) annotations.keySet().toArray(Tools.EMPTY_STRING_ARRAY);
  136. }
  137. public void setElementKey(String elementKey) {
  138. checkWritable();
  139. this.elementKey = elementKey;
  140. }
  141. public String getElementKey() {
  142. return elementKey;
  143. }
  144. /** exchange the two attribute positions */
  145. public void exchangeAttributes(int index1, int index2) {
  146. checkWritable();
  147. Attribute[] attribute = getAttributes();
  148. Attribute attribute1 = attribute[index1];
  149. Attribute attribute2 = attribute[index2];
  150. getSubEntityHandler().clearReferences();
  151. for (int i=0;i<attributes.length;i++) {
  152. if (i == index1)
  153. getSubEntityHandler().add((RefEntity)attribute2);
  154. else if (i == index2)
  155. getSubEntityHandler().add((RefEntity)attribute1);
  156. else
  157. getSubEntityHandler().add((RefEntity)attributes[i]);
  158. }
  159. attributeArrayUpToDate = false;
  160. }
  161. /** find an attribute in the dynamic-type that equals the specified attribute. */
  162. public Attribute findAttribute(Attribute copy) {
  163. return (Attribute) super.findEntity((RefEntity)copy);
  164. }
  165. public Attribute findAttributeForId(Object id) {
  166. Attribute[] typeAttributes = getAttributes();
  167. for (int i=0; i<typeAttributes.length; i++) {
  168. if (((RefEntity)typeAttributes[i]).getId().equals(id)) {
  169. return typeAttributes[i];
  170. }
  171. }
  172. return null;
  173. }
  174. public void removeAttribute(Attribute attribute) {
  175. checkWritable();
  176. if ( findAttribute( attribute ) == null) {
  177. return;
  178. }
  179. attributeArrayUpToDate = false;
  180. super.removeEntity((RefEntity) attribute);
  181. if (this.equals(attribute.getDynamicType()))
  182. ((AttributeImpl) attribute).setParent(null);
  183. }
  184. public void addAttribute(Attribute attribute) {
  185. checkWritable();
  186. attributeArrayUpToDate = false;
  187. super.addEntity((RefEntity) attribute);
  188. if (attribute.getDynamicType() != null
  189. && !this.isIdentical(attribute.getDynamicType()))
  190. throw new IllegalStateException("Attribute '" + attribute
  191. + "' belongs to another dynamicType :"
  192. + attribute.getDynamicType());
  193. ((AttributeImpl) attribute).setParent(this);
  194. }
  195. private void updateAttributeArray() {
  196. if (attributeArrayUpToDate)
  197. return;
  198. Collection attributeList = new ArrayList();
  199. Iterator it = super.getSubEntities();
  200. while (it.hasNext()) {
  201. RefEntity o = (RefEntity) it.next();
  202. if (o.getRaplaType().equals(Attribute.TYPE)) {
  203. attributeList.add(o);
  204. }
  205. }
  206. attributes = (Attribute[]) attributeList.toArray(Attribute.ATTRIBUTE_ARRAY);
  207. attributeArrayUpToDate = true;
  208. }
  209. public boolean hasAttribute(Attribute attribute) {
  210. return getReferenceHandler().isRefering((RefEntity)attribute);
  211. }
  212. public Attribute[] getAttributes() {
  213. updateAttributeArray();
  214. return attributes;
  215. }
  216. public Attribute getAttribute(String key) {
  217. Attribute[] attributes = getAttributes();
  218. for (int i=0;i<attributes.length;i++) {
  219. if (attributes[i].getKey().equals(key))
  220. return attributes[i];
  221. }
  222. return null;
  223. }
  224. ParsedAnnotation getParsedAnnotation(String key) {
  225. return (ParsedAnnotation) annotations.get( key );
  226. }
  227. static private void copy(DynamicTypeImpl source,DynamicTypeImpl dest) {
  228. dest.annotations = (HashMap) source.annotations.clone();
  229. dest.name = (MultiLanguageName) source.name.clone();
  230. dest.elementKey = source.elementKey;
  231. Iterator it = dest.getSubEntities();
  232. while ( it.hasNext()) {
  233. AttributeImpl att = (AttributeImpl) it.next();
  234. att.setParent(dest);
  235. }
  236. dest.attributeArrayUpToDate = false;
  237. }
  238. public void copy(Object obj) {
  239. super.copy((DynamicTypeImpl)obj);
  240. copy((DynamicTypeImpl) obj,this);
  241. }
  242. public Object deepClone() {
  243. DynamicTypeImpl clone = new DynamicTypeImpl();
  244. super.deepClone(clone);
  245. copy(this,clone);
  246. return clone;
  247. }
  248. public Object clone() {
  249. DynamicTypeImpl clone = new DynamicTypeImpl();
  250. super.clone(clone);
  251. copy(this,clone);
  252. return clone;
  253. }
  254. public String toString() {
  255. StringBuffer buf = new StringBuffer();
  256. buf.append(" [");
  257. buf.append ( super.toString()) ;
  258. buf.append("] key=");
  259. buf.append( getElementKey() );
  260. buf.append(": ");
  261. if ( attributes != null ) {
  262. Attribute[] att = getAttributes();
  263. for ( int i=0;i<att.length; i++){
  264. if ( i> 0)
  265. buf.append(", ");
  266. buf.append( att[i].getKey());
  267. }
  268. }
  269. return buf.toString();
  270. }
  271. /**
  272. * @param newType
  273. * @param attributeId
  274. */
  275. public boolean hasAttributeChanged(DynamicTypeImpl newType, Object attributeId) {
  276. Attribute oldAttribute = findAttributeForId(attributeId );
  277. Attribute newAttribute = newType.findAttributeForId(attributeId );
  278. if ((newAttribute == null ) || ( oldAttribute == null)) {
  279. return true;
  280. }
  281. if ( !newAttribute.getKey().equals( oldAttribute.getKey() )) {
  282. return true;
  283. }
  284. if ( !newAttribute.getType().equals( oldAttribute.getType())) {
  285. return true;
  286. }
  287. {
  288. String[] keys = newAttribute.getConstraintKeys();
  289. String[] oldKeys = oldAttribute.getConstraintKeys();
  290. if ( keys.length != oldKeys.length) {
  291. return true;
  292. }
  293. for ( int i=0;i< keys.length;i++) {
  294. if ( !keys[i].equals( oldKeys[i]) )
  295. return true;
  296. Object oldConstr = oldAttribute.getConstraint( keys[i]);
  297. Object newConstr = newAttribute.getConstraint( keys[i]);
  298. if ( oldConstr == null && newConstr == null)
  299. continue;
  300. if ( oldConstr == null || newConstr == null)
  301. return true;
  302. if ( !oldConstr.equals( newConstr))
  303. return true;
  304. }
  305. }
  306. return false;
  307. }
  308. }