KickJava   Java API By Example, From Geeks To Geeks.

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


1 /*****************************************************************
2  * Licensed to the Apache Software Foundation (ASF) under one
3  * or more contributor license agreements. See the NOTICE file
4  * distributed with this work for additional information
5  * regarding copyright ownership. The ASF licenses this file
6  * to you under the Apache License, Version 2.0 (the
7  * "License"); you may not use this file except in compliance
8  * with the License. You may obtain a copy of the License at
9  *
10  * http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing,
13  * software distributed under the License is distributed on an
14  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15  * KIND, either express or implied. See the License for the
16  * specific language governing permissions and limitations
17  * under the License.
18  ****************************************************************/

19
20 package org.apache.cayenne.map;
21
22 import java.util.ArrayList JavaDoc;
23 import java.util.Collections JavaDoc;
24 import java.util.Iterator JavaDoc;
25 import java.util.List JavaDoc;
26
27 import org.apache.cayenne.dba.TypesMapping;
28 import org.apache.cayenne.util.Util;
29 import org.apache.cayenne.util.XMLEncoder;
30
31 /**
32  * A DerivedDbAttribute is a DbAttribute that resolves to an SQL expression based on a set
33  * of other attributes. DerivedDbAttribute's allow to build expressions like "
34  * <code>count(id)</code>", "<code>sum(price)</code>", etc.
35  * <p>
36  * Internally DerivedDbAttribute is defined as a specification string and a set of
37  * substitution DbAttribute parameters. Specification string is an SQL expression that
38  * contains placeholders (<code>%@</code>) for attribute parameters, for example:
39  * </p>
40  * <p>
41  * <code>sum(%@) + sum(%@)</code>
42  * </p>
43  *
44  * @author Andrus Adamchik
45  */

46 public class DerivedDbAttribute extends DbAttribute {
47
48     public static final String JavaDoc ATTRIBUTE_TOKEN = "%@";
49
50     protected String JavaDoc expressionSpec;
51     protected List JavaDoc params = new ArrayList JavaDoc();
52     protected boolean groupBy;
53
54     /**
55      * Constructor for DerivedDbAttribute.
56      */

57     public DerivedDbAttribute() {
58         super();
59     }
60
61     /**
62      * Constructor for DerivedDbAttribute.
63      */

64     public DerivedDbAttribute(String JavaDoc name) {
65         super(name);
66     }
67
68     /**
69      * Constructor for DerivedDbAttribute.
70      */

71     public DerivedDbAttribute(String JavaDoc name, int type, DbEntity entity, String JavaDoc spec) {
72         super(name, type, entity);
73         setExpressionSpec(spec);
74     }
75
76     /**
77      * Creates and initializes a derived attribute with an attribute of a parent entity.
78      */

79     public DerivedDbAttribute(DbEntity entity, DbAttribute parentProto) {
80         setName(parentProto.getName());
81         setType(parentProto.getType());
82         setMandatory(parentProto.isMandatory());
83         setMaxLength(parentProto.getMaxLength());
84         setAttributePrecision(parentProto.getAttributePrecision());
85         setScale(parentProto.getScale());
86         setPrimaryKey(parentProto.isPrimaryKey());
87
88         setExpressionSpec(ATTRIBUTE_TOKEN);
89         addParam(parentProto);
90         setEntity(entity);
91     }
92
93     /**
94      * Prints itself as XML to the provided XMLEncoder.
95      *
96      * @since 1.1
97      */

98     public void encodeAsXML(XMLEncoder encoder) {
99         encoder.print("<db-attribute-derived name=\""
100                 + Util.encodeXmlAttribute(getName())
101                 + '\"');
102
103         String JavaDoc type = TypesMapping.getSqlNameByType(getType());
104         if (type != null) {
105             encoder.print(" type=\"" + type + '\"');
106         }
107
108         // If attribute is part of primary key
109
if (isPrimaryKey()) {
110             encoder.print(" isPrimaryKey=\"true\"");
111         }
112
113         if (isMandatory())
114             encoder.print(" isMandatory=\"true\"");
115
116         if (getMaxLength() > 0) {
117             encoder.print(" length=\"");
118             encoder.print(getMaxLength());
119             encoder.print('\"');
120         }
121
122         if (getScale() > 0) {
123             encoder.print(" scale=\"");
124             encoder.print(getScale());
125             encoder.print('\"');
126         }
127         
128         if (getAttributePrecision() > 0) {
129             encoder.print(" attributePrecision=\"");
130             encoder.print(getAttributePrecision());
131             encoder.print('\"');
132         }
133
134         if (((DerivedDbEntity) getEntity()).getGroupByAttributes().contains(this)) {
135             encoder.print(" isGroupBy=\"true\"");
136         }
137
138         String JavaDoc spec = getExpressionSpec();
139         if (spec != null && spec.trim().length() > 0) {
140             encoder.print(" spec=\"");
141             encoder.print(spec);
142             encoder.print('\"');
143         }
144
145         List JavaDoc params = getParams();
146
147         if (params.size() > 0) {
148             encoder.println(">");
149
150             encoder.indent(1);
151
152             Iterator JavaDoc refs = params.iterator();
153             while (refs.hasNext()) {
154                 DbAttribute ref = (DbAttribute) refs.next();
155                 encoder.println("<db-attribute-ref name=\""
156                         + Util.encodeXmlAttribute(ref.getName())
157                         + "\"/>");
158             }
159
160             encoder.indent(-1);
161             encoder.println("</db-attribute-derived>");
162         }
163         else {
164             encoder.println("/>");
165         }
166     }
167
168     public String JavaDoc getAliasedName(String JavaDoc alias) {
169         if (expressionSpec == null) {
170             return super.getAliasedName(alias);
171         }
172
173         int len = params.size();
174         StringBuffer JavaDoc buf = new StringBuffer JavaDoc();
175         int ind = 0;
176         for (int i = 0; i < len; i++) {
177             // no bound checking
178
// expression is assumed to be valid
179
int match = expressionSpec.indexOf(ATTRIBUTE_TOKEN, ind);
180             DbAttribute at = (DbAttribute) params.get(i);
181             if (match > i) {
182                 buf.append(expressionSpec.substring(ind, match));
183             }
184             buf.append(at.getAliasedName(alias));
185             ind = match + 2;
186         }
187
188         if (ind < expressionSpec.length()) {
189             buf.append(expressionSpec.substring(ind));
190         }
191
192         return buf.toString();
193     }
194
195     /**
196      * Returns true if this attribute is used in GROUP BY clause of the parent entity.
197      */

198     public boolean isGroupBy() {
199         return groupBy;
200     }
201
202     public void setGroupBy(boolean flag) {
203         groupBy = flag;
204     }
205
206     /**
207      * Returns the params.
208      *
209      * @return List
210      */

211     public List JavaDoc getParams() {
212         return Collections.unmodifiableList(params);
213     }
214
215     /**
216      * Returns the expressionSpec.
217      */

218     public String JavaDoc getExpressionSpec() {
219         return expressionSpec;
220     }
221
222     /**
223      * Adds parameter.
224      */

225     public void addParam(DbAttribute param) {
226         params.add(param);
227     }
228
229     public void removeParam(DbAttribute param) {
230         params.remove(param);
231     }
232
233     public void clearParams() {
234         params.clear();
235     }
236
237     /**
238      * Sets the expressionSpec.
239      */

240     public void setExpressionSpec(String JavaDoc expressionSpec) {
241         this.expressionSpec = expressionSpec;
242     }
243 }
244
Popular Tags