View Javadoc
1   /*
2    * (c) Copyright 2006-2020 by rapiddweller GmbH & Volker Bergmann. All rights reserved.
3    *
4    * Redistribution and use in source and binary forms, with or without
5    * modification, is permitted under the terms of the
6    * GNU General Public License.
7    *
8    * For redistributing this software or a derivative work under a license other
9    * than the GPL-compatible Free Software License as defined by the Free
10   * Software Foundation or approved by OSI, you must first obtain a commercial
11   * license to this software product from rapiddweller GmbH & Volker Bergmann.
12   *
13   * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
14   * WITHOUT A WARRANTY OF ANY KIND. ALL EXPRESS OR IMPLIED CONDITIONS,
15   * REPRESENTATIONS AND WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF
16   * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE
17   * HEREBY EXCLUDED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
18   * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
19   * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
20   * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
21   * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
22   * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
23   * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
24   * POSSIBILITY OF SUCH DAMAGE.
25   */
26  
27  package com.rapiddweller.model.data;
28  
29  import com.rapiddweller.common.Composite;
30  import com.rapiddweller.common.CompositeFormatter;
31  import com.rapiddweller.common.ConfigurationError;
32  import com.rapiddweller.common.collection.OrderedNameMap;
33  import com.rapiddweller.common.converter.AnyConverter;
34  import com.rapiddweller.platform.java.BeanDescriptorProvider;
35  import com.rapiddweller.script.PrimitiveType;
36  
37  /**
38   * Instance of a composite data type as described by a {@link ComplexTypeDescriptor}.<br/>
39   * <br/>
40   * Created: 20.08.2007 19:20:22
41   *
42   * @author Volker Bergmann
43   * @since 0.3
44   */
45  public class Entity implements Composite {
46  
47    /**
48     * The Descriptor.
49     */
50    public final ComplexTypeDescriptor descriptor;
51    private OrderedNameMap<Object> components;
52  
53    // constructors ----------------------------------------------------------------------------------------------------
54  
55    /**
56     * Instantiates a new Entity.
57     *
58     * @param name               the name
59     * @param descriptorProvider the descriptor provider
60     */
61    public Entity(String name, DescriptorProvider descriptorProvider) {
62      this(new ComplexTypeDescriptor(name, descriptorProvider));
63    }
64  
65    /**
66     * Instantiates a new Entity.
67     *
68     * @param name                   the name
69     * @param descriptorProvider     the descriptor provider
70     * @param componentKeyValuePairs the component key value pairs
71     */
72    public Entity(String name, DescriptorProvider descriptorProvider,
73                  Object... componentKeyValuePairs) {
74      this(new ComplexTypeDescriptor(name, descriptorProvider),
75          componentKeyValuePairs);
76    }
77  
78    /**
79     * Instantiates a new Entity.
80     *
81     * @param descriptor             the name of the entity, it may be null
82     * @param componentKeyValuePairs content of Entity column and value
83     */
84    public Entity(ComplexTypeDescriptor descriptor,
85                  Object... componentKeyValuePairs) {
86      this.descriptor = descriptor;
87      this.components = OrderedNameMap.createCaseInsensitiveMap();
88      for (int i = 0; i < componentKeyValuePairs.length; i += 2) {
89        setComponent((String) componentKeyValuePairs[i],
90            componentKeyValuePairs[i + 1]);
91      }
92    }
93  
94    /**
95     * Instantiates a new Entity.
96     *
97     * @param prototype the prototype
98     */
99    public Entityty" href="../../../../com/rapiddweller/model/data/Entity.html#Entity">Entity(Entity prototype) {
100     this.descriptor = prototype.descriptor;
101     this.components = new OrderedNameMap<>(prototype.components);
102   }
103 
104   // interface -------------------------------------------------------------------------------------------------------
105 
106   /**
107    * Type string.
108    *
109    * @return the string
110    */
111   public String type() {
112     return (descriptor != null ? descriptor.getName() : null);
113   }
114 
115   /**
116    * Descriptor complex type descriptor.
117    *
118    * @return the complex type descriptor
119    */
120   public ComplexTypeDescriptor descriptor() {
121     return descriptor;
122   }
123 
124   /**
125    * Allows for generic 'map-like' access to component values, e.g. by FreeMarker.
126    *
127    * @param componentName the name of the component whose value to return.
128    * @return the value of the specified component.
129    * @since 0.4.0
130    */
131   public Object get(String componentName) {
132     return getComponent(componentName);
133   }
134 
135   @Override
136   public Object getComponent(String componentName) {
137     return components.get(componentName);
138   }
139 
140   /**
141    * Component is set boolean.
142    *
143    * @param componentName the component name
144    * @return the boolean
145    */
146   public boolean componentIsSet(String componentName) {
147     return components.containsKey(componentName);
148   }
149 
150   @Override
151   public OrderedNameMap<Object> getComponents() {
152     return components;
153   }
154 
155   /**
156    * Sets components.
157    *
158    * @param components the components
159    */
160   public void setComponents(OrderedNameMap<Object> components) {
161     this.components = components;
162   }
163 
164   /**
165    * Set.
166    *
167    * @param componentName the component name
168    * @param component     the component
169    */
170   public void set(String componentName, Object component) {
171     setComponent(componentName, component);
172   }
173 
174   @Override
175   public void setComponent(String componentName, Object component) {
176     ComponentDescriptor componentDescriptor = null;
177     if (descriptor != null) {
178       componentDescriptor = descriptor.getComponent(componentName);
179     }
180     if (componentDescriptor != null && componentDescriptor
181         .getTypeDescriptor() instanceof SimpleTypeDescriptor) {
182       SimpleTypeDescriptor componentType =
183           (SimpleTypeDescriptor) componentDescriptor
184               .getTypeDescriptor();
185       PrimitiveType primitiveType = componentType.getPrimitiveType();
186       if (primitiveType == null) {
187         primitiveType = PrimitiveType.STRING;
188       }
189       BeanDescriptorProvider beanProvider =
190           descriptor.getDataModel().getBeanDescriptorProvider();
191       Class<?> javaType =
192           beanProvider.concreteType(primitiveType.getName());
193       component = AnyConverter.convert(component, javaType);
194     }
195     String internalComponentName =
196         componentDescriptor != null ? componentDescriptor.getName() :
197             componentName;
198     components.put(internalComponentName, component);
199   }
200 
201   /**
202    * Remove.
203    *
204    * @param componentName the component name
205    */
206   public void remove(String componentName) {
207     removeComponent(componentName);
208   }
209 
210   /**
211    * Remove component.
212    *
213    * @param componentName the component name
214    */
215   public void removeComponent(String componentName) {
216     components.remove(componentName);
217   }
218 
219   /**
220    * Id component values object.
221    *
222    * @return the object
223    */
224   public Object idComponentValues() {
225     ComplexTypeDescriptor entityDescriptor = descriptor;
226     if (entityDescriptor == null) {
227       throw new ConfigurationError("Unknown type: " + this);
228     }
229     String[] idComponentNames = entityDescriptor.getIdComponentNames();
230     if (idComponentNames.length == 1) {
231       return get(idComponentNames[0]);
232     } else if (idComponentNames.length == 0) {
233       return null;
234     } else {
235       return componentValues(idComponentNames);
236     }
237   }
238 
239   /**
240    * Component values object.
241    *
242    * @param idComponentNames the id component names
243    * @return the object
244    */
245   public Object componentValues(String[] idComponentNames) {
246     Object[] result = new Object[idComponentNames.length];
247     for (int i = 0; i < idComponentNames.length; i++) {
248       result[i] = get(idComponentNames[i]);
249     }
250     return result;
251   }
252 
253   // java.lang.overrides ---------------------------------------------------------------------------------------------
254 
255   @Override
256   public boolean equals(Object o) {
257     if (this == o) {
258       return true;
259     }
260     if (!(o instanceof Entity)) {
261       return false;
262     }
263     final Entity="../../../../com/rapiddweller/model/data/Entity.html#Entity">Entity that = (Entity) o;
264     if (!this.descriptor.getName().equals(that.descriptor.getName())) {
265       return false;
266     }
267     return this.components.equalsIgnoreOrder(that.components);
268   }
269 
270   @Override
271   public int hashCode() {
272     return descriptor.getName().hashCode() * 29 + components.hashCode();
273   }
274 
275   @Override
276   public String toString() {
277     return new CompositeFormatter(true, true)
278         .render(type() + '[', this, "]");
279   }
280 
281 }