Source code: org/objectstyle/cayenne/map/DerivedDbAttribute.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 package org.objectstyle.cayenne.map;
57
58 import java.util.ArrayList;
59 import java.util.Collections;
60 import java.util.List;
61
62 /**
63 * A DerivedDbAttribute is a DbAttribute that resolves to an SQL expression based on
64 * a set of other attributes. DerivedDbAttribute's allow to build
65 * expressions like "<code>count(id)</code>", "<code>sum(price)</code>", etc.
66 *
67 * <p>
68 * Internally DerivedDbAttribute is defined as a specification string and a set of
69 * substitution DbAttribute parameters. Specification string is an SQL expression that contains
70 * placeholders (<code>%@</code>) for attribute parameters, for example:
71 * </p>
72 *
73 * <p><code>sum(%@) + sum(%@)</code></p>
74 *
75 *
76 * @author Andrei Adamchik
77 */
78 public class DerivedDbAttribute extends DbAttribute {
79 public static final String ATTRIBUTE_TOKEN = "%@";
80
81 protected String expressionSpec;
82 protected List params = new ArrayList();
83 protected boolean groupBy;
84
85 /**
86 * Constructor for DerivedDbAttribute.
87 */
88 public DerivedDbAttribute() {
89 super();
90 }
91
92 /**
93 * Constructor for DerivedDbAttribute.
94 */
95 public DerivedDbAttribute(String name) {
96 super(name);
97 }
98
99 /**
100 * Constructor for DerivedDbAttribute.
101 *
102 */
103 public DerivedDbAttribute(String name, int type, DbEntity entity, String spec) {
104 super(name, type, entity);
105 setExpressionSpec(spec);
106 }
107
108
109 /**
110 * Creates and initializes a derived attribute with
111 * an attribute of a parent entity.
112 */
113 public DerivedDbAttribute(DbEntity entity, DbAttribute parentProto) {
114 setName(parentProto.getName());
115 setType(parentProto.getType());
116 setMandatory(parentProto.isMandatory());
117 setMaxLength(parentProto.getMaxLength());
118 setPrecision(parentProto.getPrecision());
119 setPrimaryKey(parentProto.isPrimaryKey());
120
121 setExpressionSpec(ATTRIBUTE_TOKEN);
122 addParam(parentProto);
123 setEntity(entity);
124 }
125
126 public String getAliasedName(String alias) {
127 if (expressionSpec == null) {
128 return super.getAliasedName(alias);
129 }
130
131 int len = params.size();
132 StringBuffer buf = new StringBuffer();
133 int ind = 0;
134 for (int i = 0; i < len; i++) {
135 // no bound checking
136 // expression is assumed to be valid
137 int match = expressionSpec.indexOf(ATTRIBUTE_TOKEN, ind);
138 DbAttribute at = (DbAttribute) params.get(i);
139 if (match > i) {
140 buf.append(expressionSpec.substring(ind, match));
141 }
142 buf.append(at.getAliasedName(alias));
143 ind = match + 2;
144 }
145
146 if (ind < expressionSpec.length()) {
147 buf.append(expressionSpec.substring(ind));
148 }
149
150 return buf.toString();
151 }
152
153 /**
154 * Returns true if this attribute is used in GROUP BY
155 * clause of the parent entity.
156 */
157 public boolean isGroupBy() {
158 return groupBy;
159 }
160
161 public void setGroupBy(boolean flag) {
162 groupBy = flag;
163 }
164
165 /**
166 * Returns the params.
167 * @return List
168 */
169 public List getParams() {
170 return Collections.unmodifiableList(params);
171 }
172
173 /**
174 * Returns the expressionSpec.
175 * @return String
176 */
177 public String getExpressionSpec() {
178 return expressionSpec;
179 }
180
181 /**
182 * Sets the params.
183 * @param params The expParams to set
184 */
185 public void addParam(DbAttribute param) {
186 params.add(param);
187 }
188
189 public void removeParam(DbAttribute param) {
190 params.remove(param);
191 }
192
193 public void clearParams() {
194 params.clear();
195 }
196
197 /**
198 * Sets the expressionSpec.
199 * @param expressionSpec The expressionSpec to set
200 */
201 public void setExpressionSpec(String expressionSpec) {
202 this.expressionSpec = expressionSpec;
203 }
204 }