Source code: org/objectstyle/cayenne/map/ObjAttribute.java
1 /* ====================================================================
2 *
3 * The ObjectStyle Group Software License, Version 1.0
4 *
5 * Copyright (c) 2002-2003 The ObjectStyle Group
6 * and individual authors of the software. All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 *
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 *
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in
17 * the documentation and/or other materials provided with the
18 * distribution.
19 *
20 * 3. The end-user documentation included with the redistribution, if
21 * any, must include the following acknowlegement:
22 * "This product includes software developed by the
23 * ObjectStyle Group (http://objectstyle.org/)."
24 * Alternately, this acknowlegement may appear in the software itself,
25 * if and wherever such third-party acknowlegements normally appear.
26 *
27 * 4. The names "ObjectStyle Group" and "Cayenne"
28 * must not be used to endorse or promote products derived
29 * from this software without prior written permission. For written
30 * permission, please contact andrus@objectstyle.org.
31 *
32 * 5. Products derived from this software may not be called "ObjectStyle"
33 * nor may "ObjectStyle" appear in their names without prior written
34 * permission of the ObjectStyle Group.
35 *
36 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
37 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
38 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
39 * DISCLAIMED. IN NO EVENT SHALL THE OBJECTSTYLE GROUP OR
40 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
41 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
42 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
43 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
44 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
45 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
46 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
47 * SUCH DAMAGE.
48 * ====================================================================
49 *
50 * This software consists of voluntary contributions made by many
51 * individuals on behalf of the ObjectStyle Group. For more
52 * information on the ObjectStyle Group, please see
53 * <http://objectstyle.org/>.
54 *
55 */
56
57 package org.objectstyle.cayenne.map;
58
59 import java.util.Iterator;
60
61 import org.apache.commons.collections.IteratorUtils;
62 import org.apache.commons.lang.StringUtils;
63 import org.objectstyle.cayenne.CayenneException;
64
65 /**
66 * An ObjAttribute is a mapping descriptor of a Java class property.
67 *
68 * @author Misha Shengaout
69 * @author Andrei Adamchik
70 */
71 public class ObjAttribute extends Attribute {
72 // Full name of Java class representing the property type.
73 protected String attrType;
74
75 // The name of the corresponding database table column
76 private String dbAttributePath;
77
78 public ObjAttribute() {}
79
80 public ObjAttribute(String name) {
81 super(name);
82 }
83
84
85 public ObjAttribute(String name, String type, ObjEntity entity) {
86 setName(name);
87 setType(type);
88 setEntity(entity);
89 }
90
91
92 /** Gets the type of the data object property.
93 * Type returned is a string that specifies full name of a Java class
94 * used to represent this attribute. */
95 public String getType() {
96 return attrType;
97 }
98
99
100 /** Sets the type of the data object property.*/
101 public void setType(String type) {
102 this.attrType = type;
103 }
104
105
106 /**
107 * Returns an attribute describing a mapped database
108 * table column.
109 */
110 public DbAttribute getDbAttribute() {
111 Iterator pathIterator = getDbPathIterator();
112 Object o = null;
113 while (pathIterator.hasNext()) {
114 o = pathIterator.next();
115 }
116 return (DbAttribute)o;
117 }
118
119 public Iterator getDbPathIterator() {
120 if(dbAttributePath == null) {
121 return IteratorUtils.EMPTY_ITERATOR;
122 }
123
124 ObjEntity ent = (ObjEntity)getEntity();
125 if(ent == null) {
126 return IteratorUtils.EMPTY_ITERATOR;
127 }
128
129 DbEntity dbEnt = ent.getDbEntity();
130 if(dbEnt == null) {
131 return IteratorUtils.EMPTY_ITERATOR;
132 }
133
134 int lastPartStart = dbAttributePath.lastIndexOf('.');
135 if (lastPartStart < 0) {
136 Attribute attribute = dbEnt.getAttribute(dbAttributePath);
137 if (attribute == null) {
138 return IteratorUtils.EMPTY_ITERATOR;
139 }
140 return IteratorUtils.singletonIterator(attribute);
141 }
142
143 return dbEnt.resolvePathComponents(dbAttributePath);
144 }
145
146
147 /** Set the corresponding database table column.
148 * @see org.objectstyle.cayenne.map.DbAttribute#getName() */
149 public void setDbAttribute(DbAttribute dbAttribute) {
150 if(dbAttribute == null) {
151 this.setDbAttributePath(null);
152 }
153 else {
154 this.setDbAttributePath(dbAttribute.getName());
155 }
156 }
157
158
159 /**
160 * Returns the dbAttributeName.
161 * @return String
162 */
163 public String getDbAttributeName() {
164 if (dbAttributePath == null) return null;
165 int lastPartStart = dbAttributePath.lastIndexOf('.');
166 String lastPart = StringUtils.substring(
167 dbAttributePath,
168 lastPartStart + 1,
169 dbAttributePath.length());
170 return lastPart;
171 }
172
173
174 /**
175 * Sets the dbAttributeName.
176 * @param dbAttributeName The dbAttributeName to set
177 */
178 public void setDbAttributeName(String dbAttributeName) {
179 if (dbAttributePath == null || dbAttributeName == null) {
180 dbAttributePath = dbAttributeName;
181 return;
182 }
183 int lastPartStart = dbAttributePath.lastIndexOf('.');
184 String newPath = (lastPartStart > 0
185 ? StringUtils.chomp(dbAttributePath, ".")
186 : "");
187 newPath += (newPath.length() > 0 ? "." : "") + dbAttributeName;
188 this.dbAttributePath = newPath;
189 }
190
191 public void setDbAttributePath(String dbAttributePath) {
192 this.dbAttributePath = dbAttributePath;
193 }
194
195 public String getDbAttributePath() {
196 return dbAttributePath;
197 }
198
199 public boolean isCompound() {
200 return (dbAttributePath != null && dbAttributePath.indexOf('.') >= 0);
201 }
202
203 public boolean mapsToDependentDbEntity() {
204 Iterator i = getDbPathIterator();
205 if (!i.hasNext()) return false;
206 Object o = i.next();
207 if (!i.hasNext()) return false;
208 Object o1 = i.next();
209 if (!(o1 instanceof DbAttribute)) return false;
210 DbRelationship toDependent = (DbRelationship)o;
211 return toDependent.isToDependentPK();
212 }
213
214 public void validate() throws CayenneException {
215 String head = "ObjAttribute: " + getName() + " ";
216 ObjEntity ent = (ObjEntity)getEntity();
217 if(ent == null) {
218 throw new CayenneException(head + "Parent ObjEntity not defined.");
219 }
220 head += "ObjEntity: " + ent.getName() + " ";
221
222 if (getName() == null)
223 throw new CayenneException(head + "ObjAttribute's name not defined.");
224
225 if (getDbAttributePath() == null)
226 throw new CayenneException(head + "dbAttributePath not defined.");
227
228 try {
229 Iterator i = getDbPathIterator();
230 boolean dbAttributeFound = false;
231 while (i.hasNext()) {
232 Object pathPart = i.next();
233 if (pathPart instanceof DbRelationship) {
234 DbRelationship r = (DbRelationship)pathPart;
235 if (r.isToMany())
236 throw new CayenneException(
237 head + "DbRelationship: " + r.getName() + " is to-many.");
238 } else if (pathPart instanceof DbAttribute) {
239 dbAttributeFound = true;
240 }
241 }
242 if (!dbAttributeFound)
243 throw new CayenneException(head + "DbAttribute not found.");
244 } catch (CayenneException ex) {
245 throw ex;
246 } catch (Exception ex) {
247 throw new CayenneException(head + ex.getMessage(), ex);
248 }
249 }
250 }