KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > objectstyle > cayenne > map > DerivedDbAttribute


1 /* ====================================================================
2  *
3  * The ObjectStyle Group Software License, version 1.1
4  * ObjectStyle Group - http://objectstyle.org/
5  *
6  * Copyright (c) 2002-2005, Andrei (Andrus) Adamchik and individual authors
7  * of the software. All rights reserved.
8  *
9  * Redistribution and use in source and binary forms, with or without
10  * modification, are permitted provided that the following conditions
11  * are met:
12  *
13  * 1. Redistributions of source code must retain the above copyright
14  * notice, this list of conditions and the following disclaimer.
15  *
16  * 2. Redistributions in binary form must reproduce the above copyright
17  * notice, this list of conditions and the following disclaimer in
18  * the documentation and/or other materials provided with the
19  * distribution.
20  *
21  * 3. The end-user documentation included with the redistribution, if any,
22  * must include the following acknowlegement:
23  * "This product includes software developed by independent contributors
24  * and hosted on ObjectStyle Group web site (http://objectstyle.org/)."
25  * Alternately, this acknowlegement may appear in the software itself,
26  * if and wherever such third-party acknowlegements normally appear.
27  *
28  * 4. The names "ObjectStyle Group" and "Cayenne" must not be used to endorse
29  * or promote products derived from this software without prior written
30  * permission. For written permission, email
31  * "andrus at objectstyle dot org".
32  *
33  * 5. Products derived from this software may not be called "ObjectStyle"
34  * or "Cayenne", nor may "ObjectStyle" or "Cayenne" appear in their
35  * names without prior written permission.
36  *
37  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
38  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
39  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
40  * DISCLAIMED. IN NO EVENT SHALL THE OBJECTSTYLE GROUP OR
41  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
42  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
43  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
44  * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
45  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
46  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
47  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
48  * SUCH DAMAGE.
49  * ====================================================================
50  *
51  * This software consists of voluntary contributions made by many
52  * individuals and hosted on ObjectStyle Group web site. For more
53  * information on the ObjectStyle Group, please see
54  * <http://objectstyle.org/>.
55  */

56 package org.objectstyle.cayenne.map;
57
58 import java.util.ArrayList JavaDoc;
59 import java.util.Collections JavaDoc;
60 import java.util.Iterator JavaDoc;
61 import java.util.List JavaDoc;
62
63 import org.objectstyle.cayenne.dba.TypesMapping;
64 import org.objectstyle.cayenne.util.Util;
65 import org.objectstyle.cayenne.util.XMLEncoder;
66
67 /**
68  * A DerivedDbAttribute is a DbAttribute that resolves to an SQL expression based on a set
69  * of other attributes. DerivedDbAttribute's allow to build expressions like "
70  * <code>count(id)</code>", "<code>sum(price)</code>", etc.
71  * <p>
72  * Internally DerivedDbAttribute is defined as a specification string and a set of
73  * substitution DbAttribute parameters. Specification string is an SQL expression that
74  * contains placeholders (<code>%@</code>) for attribute parameters, for example:
75  * </p>
76  * <p>
77  * <code>sum(%@) + sum(%@)</code>
78  * </p>
79  *
80  * @author Andrei Adamchik
81  */

82 public class DerivedDbAttribute extends DbAttribute {
83
84     public static final String JavaDoc ATTRIBUTE_TOKEN = "%@";
85
86     protected String JavaDoc expressionSpec;
87     protected List JavaDoc params = new ArrayList JavaDoc();
88     protected boolean groupBy;
89
90     /**
91      * Constructor for DerivedDbAttribute.
92      */

93     public DerivedDbAttribute() {
94         super();
95     }
96
97     /**
98      * Constructor for DerivedDbAttribute.
99      */

100     public DerivedDbAttribute(String JavaDoc name) {
101         super(name);
102     }
103
104     /**
105      * Constructor for DerivedDbAttribute.
106      */

107     public DerivedDbAttribute(String JavaDoc name, int type, DbEntity entity, String JavaDoc spec) {
108         super(name, type, entity);
109         setExpressionSpec(spec);
110     }
111
112     /**
113      * Creates and initializes a derived attribute with an attribute of a parent entity.
114      */

115     public DerivedDbAttribute(DbEntity entity, DbAttribute parentProto) {
116         setName(parentProto.getName());
117         setType(parentProto.getType());
118         setMandatory(parentProto.isMandatory());
119         setMaxLength(parentProto.getMaxLength());
120         setPrecision(parentProto.getPrecision());
121         setPrimaryKey(parentProto.isPrimaryKey());
122
123         setExpressionSpec(ATTRIBUTE_TOKEN);
124         addParam(parentProto);
125         setEntity(entity);
126     }
127
128     /**
129      * Prints itself as XML to the provided XMLEncoder.
130      *
131      * @since 1.1
132      */

133     public void encodeAsXML(XMLEncoder encoder) {
134         encoder.print("<db-attribute-derived name=\""
135                 + Util.encodeXmlAttribute(getName())
136                 + '\"');
137
138         String JavaDoc type = TypesMapping.getSqlNameByType(getType());
139         if (type != null) {
140             encoder.print(" type=\"" + type + '\"');
141         }
142
143         // If attribute is part of primary key
144
if (isPrimaryKey()) {
145             encoder.print(" isPrimaryKey=\"true\"");
146         }
147
148         if (isMandatory())
149             encoder.print(" isMandatory=\"true\"");
150
151         if (getMaxLength() > 0) {
152             encoder.print(" length=\"");
153             encoder.print(getMaxLength());
154             encoder.print('\"');
155         }
156
157         if (getPrecision() > 0) {
158             encoder.print(" precision=\"");
159             encoder.print(getPrecision());
160             encoder.print('\"');
161         }
162
163         if (((DerivedDbEntity) getEntity()).getGroupByAttributes().contains(this)) {
164             encoder.print(" isGroupBy=\"true\"");
165         }
166
167         String JavaDoc spec = getExpressionSpec();
168         if (spec != null && spec.trim().length() > 0) {
169             encoder.print(" spec=\"");
170             encoder.print(spec);
171             encoder.print('\"');
172         }
173
174         List JavaDoc params = getParams();
175
176         if (params.size() > 0) {
177             encoder.println(">");
178
179             encoder.indent(1);
180
181             Iterator JavaDoc refs = params.iterator();
182             while (refs.hasNext()) {
183                 DbAttribute ref = (DbAttribute) refs.next();
184                 encoder.println("<db-attribute-ref name=\""
185                         + Util.encodeXmlAttribute(ref.getName())
186                         + "\"/>");
187             }
188
189             encoder.indent(-1);
190             encoder.println("</db-attribute-derived>");
191         }
192         else {
193             encoder.println("/>");
194         }
195     }
196
197     public String JavaDoc getAliasedName(String JavaDoc alias) {
198         if (expressionSpec == null) {
199             return super.getAliasedName(alias);
200         }
201
202         int len = params.size();
203         StringBuffer JavaDoc buf = new StringBuffer JavaDoc();
204         int ind = 0;
205         for (int i = 0; i < len; i++) {
206             // no bound checking
207
// expression is assumed to be valid
208
int match = expressionSpec.indexOf(ATTRIBUTE_TOKEN, ind);
209             DbAttribute at = (DbAttribute) params.get(i);
210             if (match > i) {
211                 buf.append(expressionSpec.substring(ind, match));
212             }
213             buf.append(at.getAliasedName(alias));
214             ind = match + 2;
215         }
216
217         if (ind < expressionSpec.length()) {
218             buf.append(expressionSpec.substring(ind));
219         }
220
221         return buf.toString();
222     }
223
224     /**
225      * Returns true if this attribute is used in GROUP BY clause of the parent entity.
226      */

227     public boolean isGroupBy() {
228         return groupBy;
229     }
230
231     public void setGroupBy(boolean flag) {
232         groupBy = flag;
233     }
234
235     /**
236      * Returns the params.
237      *
238      * @return List
239      */

240     public List JavaDoc getParams() {
241         return Collections.unmodifiableList(params);
242     }
243
244     /**
245      * Returns the expressionSpec.
246      */

247     public String JavaDoc getExpressionSpec() {
248         return expressionSpec;
249     }
250
251     /**
252      * Adds parameter.
253      */

254     public void addParam(DbAttribute param) {
255         params.add(param);
256     }
257
258     public void removeParam(DbAttribute param) {
259         params.remove(param);
260     }
261
262     public void clearParams() {
263         params.clear();
264     }
265
266     /**
267      * Sets the expressionSpec.
268      */

269     public void setExpressionSpec(String JavaDoc expressionSpec) {
270         this.expressionSpec = expressionSpec;
271     }
272 }
Popular Tags