1 /*
2 * Hibernate, Relational Persistence for Idiomatic Java
3 *
4 * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
5 * indicated by the @author tags or express copyright attribution
6 * statements applied by the authors. All third-party contributions are
7 * distributed under license by Red Hat Middleware LLC.
8 *
9 * This copyrighted material is made available to anyone wishing to use, modify,
10 * copy, or redistribute it subject to the terms and conditions of the GNU
11 * Lesser General Public License, as published by the Free Software Foundation.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
15 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
16 * for more details.
17 *
18 * You should have received a copy of the GNU Lesser General Public License
19 * along with this distribution; if not, write to:
20 * Free Software Foundation, Inc.
21 * 51 Franklin Street, Fifth Floor
22 * Boston, MA 02110-1301 USA
23 *
24 */
25 package org.hibernate.mapping;
26
27 import java.util.ArrayList;
28 import java.util.HashMap;
29 import java.util.Iterator;
30 import java.util.Map;
31
32 import org.hibernate.EntityMode;
33 import org.hibernate.MappingException;
34 import org.hibernate.tuple.component.ComponentMetamodel;
35 import org.hibernate.type.ComponentType;
36 import org.hibernate.type.EmbeddedComponentType;
37 import org.hibernate.type.Type;
38 import org.hibernate.util.JoinedIterator;
39 import org.hibernate.util.ReflectHelper;
40
41 /**
42 * The mapping for a component, composite element,
43 * composite identifier, etc.
44 * @author Gavin King
45 */
46 public class Component extends SimpleValue implements MetaAttributable {
47
48 private ArrayList properties = new ArrayList();
49 private String componentClassName;
50 private boolean embedded;
51 private String parentProperty;
52 private PersistentClass owner;
53 private boolean dynamic;
54 private Map metaAttributes;
55 private String nodeName;
56 private boolean isKey;
57 private String roleName;
58
59 private java.util.Map tuplizerImpls;
60
61 public Component(PersistentClass owner) throws MappingException {
62 super( owner.getTable() );
63 this.owner = owner;
64 }
65
66 public Component(Component component) throws MappingException {
67 super( component.getTable() );
68 this.owner = component.getOwner();
69 }
70
71 public Component(Join join) throws MappingException {
72 super( join.getTable() );
73 this.owner = join.getPersistentClass();
74 }
75
76 public Component(Collection collection) throws MappingException {
77 super( collection.getCollectionTable() );
78 this.owner = collection.getOwner();
79 }
80
81 public int getPropertySpan() {
82 return properties.size();
83 }
84 public Iterator getPropertyIterator() {
85 return properties.iterator();
86 }
87 public void addProperty(Property p) {
88 properties.add(p);
89 }
90 public void addColumn(Column column) {
91 throw new UnsupportedOperationException("Cant add a column to a component");
92 }
93 public int getColumnSpan() {
94 int n=0;
95 Iterator iter = getPropertyIterator();
96 while ( iter.hasNext() ) {
97 Property p = (Property) iter.next();
98 n+= p.getColumnSpan();
99 }
100 return n;
101 }
102 public Iterator getColumnIterator() {
103 Iterator[] iters = new Iterator[ getPropertySpan() ];
104 Iterator iter = getPropertyIterator();
105 int i=0;
106 while ( iter.hasNext() ) {
107 iters[i++] = ( (Property) iter.next() ).getColumnIterator();
108 }
109 return new JoinedIterator(iters);
110 }
111
112 public void setTypeByReflection(String propertyClass, String propertyName) {}
113
114 public boolean isEmbedded() {
115 return embedded;
116 }
117
118 public String getComponentClassName() {
119 return componentClassName;
120 }
121
122 public Class getComponentClass() throws MappingException {
123 try {
124 return ReflectHelper.classForName(componentClassName);
125 }
126 catch (ClassNotFoundException cnfe) {
127 throw new MappingException("component class not found: " + componentClassName, cnfe);
128 }
129 }
130
131 public PersistentClass getOwner() {
132 return owner;
133 }
134
135 public String getParentProperty() {
136 return parentProperty;
137 }
138
139 public void setComponentClassName(String componentClass) {
140 this.componentClassName = componentClass;
141 }
142
143 public void setEmbedded(boolean embedded) {
144 this.embedded = embedded;
145 }
146
147 public void setOwner(PersistentClass owner) {
148 this.owner = owner;
149 }
150
151 public void setParentProperty(String parentProperty) {
152 this.parentProperty = parentProperty;
153 }
154
155 public boolean isDynamic() {
156 return dynamic;
157 }
158
159 public void setDynamic(boolean dynamic) {
160 this.dynamic = dynamic;
161 }
162
163 private Type type;
164
165 public Type getType() throws MappingException {
166 // added this caching as I noticed that getType() is being called multiple times...
167 if ( type == null ) {
168 type = buildType();
169 }
170 return type;
171 }
172
173 private Type buildType() {
174 // TODO : temporary initial step towards HHH-1907
175 ComponentMetamodel metamodel = new ComponentMetamodel( this );
176 if ( isEmbedded() ) {
177 return new EmbeddedComponentType( metamodel );
178 }
179 else {
180 return new ComponentType( metamodel );
181 }
182 }
183
184 public void setTypeUsingReflection(String className, String propertyName)
185 throws MappingException {
186 }
187
188 public java.util.Map getMetaAttributes() {
189 return metaAttributes;
190 }
191 public MetaAttribute getMetaAttribute(String attributeName) {
192 return metaAttributes==null?null:(MetaAttribute) metaAttributes.get(attributeName);
193 }
194
195 public void setMetaAttributes(java.util.Map metas) {
196 this.metaAttributes = metas;
197 }
198
199 public Object accept(ValueVisitor visitor) {
200 return visitor.accept(this);
201 }
202
203 public boolean[] getColumnInsertability() {
204 boolean[] result = new boolean[ getColumnSpan() ];
205 Iterator iter = getPropertyIterator();
206 int i=0;
207 while ( iter.hasNext() ) {
208 Property prop = (Property) iter.next();
209 boolean[] chunk = prop.getValue().getColumnInsertability();
210 if ( prop.isInsertable() ) {
211 System.arraycopy(chunk, 0, result, i, chunk.length);
212 }
213 i+=chunk.length;
214 }
215 return result;
216 }
217
218 public boolean[] getColumnUpdateability() {
219 boolean[] result = new boolean[ getColumnSpan() ];
220 Iterator iter = getPropertyIterator();
221 int i=0;
222 while ( iter.hasNext() ) {
223 Property prop = (Property) iter.next();
224 boolean[] chunk = prop.getValue().getColumnUpdateability();
225 if ( prop.isUpdateable() ) {
226 System.arraycopy(chunk, 0, result, i, chunk.length);
227 }
228 i+=chunk.length;
229 }
230 return result;
231 }
232
233 public String getNodeName() {
234 return nodeName;
235 }
236
237 public void setNodeName(String nodeName) {
238 this.nodeName = nodeName;
239 }
240
241 public boolean isKey() {
242 return isKey;
243 }
244
245 public void setKey(boolean isKey) {
246 this.isKey = isKey;
247 }
248
249 public boolean hasPojoRepresentation() {
250 return componentClassName!=null;
251 }
252
253 public void addTuplizer(EntityMode entityMode, String implClassName) {
254 if ( tuplizerImpls == null ) {
255 tuplizerImpls = new HashMap();
256 }
257 tuplizerImpls.put( entityMode, implClassName );
258 }
259
260 public String getTuplizerImplClassName(EntityMode mode) {
261 // todo : remove this once ComponentMetamodel is complete and merged
262 if ( tuplizerImpls == null ) {
263 return null;
264 }
265 return ( String ) tuplizerImpls.get( mode );
266 }
267
268 public Map getTuplizerMap() {
269 if ( tuplizerImpls == null ) {
270 return null;
271 }
272 return java.util.Collections.unmodifiableMap( tuplizerImpls );
273 }
274
275 public Property getProperty(String propertyName) throws MappingException {
276 Iterator iter = getPropertyIterator();
277 while ( iter.hasNext() ) {
278 Property prop = (Property) iter.next();
279 if ( prop.getName().equals(propertyName) ) {
280 return prop;
281 }
282 }
283 throw new MappingException("component property not found: " + propertyName);
284 }
285
286 public String getRoleName() {
287 return roleName;
288 }
289
290 public void setRoleName(String roleName) {
291 this.roleName = roleName;
292 }
293
294 public String toString() {
295 return getClass().getName() + '(' + properties.toString() + ')';
296 }
297
298 }