001: ///////////////////////////////
002: // Makumba, Makumba tag library
003: // Copyright (C) 2000-2003 http://www.makumba.org
004: //
005: // This library is free software; you can redistribute it and/or
006: // modify it under the terms of the GNU Lesser General Public
007: // License as published by the Free Software Foundation; either
008: // version 2.1 of the License, or (at your option) any later version.
009: //
010: // This library is distributed in the hope that it will be useful,
011: // but WITHOUT ANY WARRANTY; without even the implied warranty of
012: // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
013: // Lesser General Public License for more details.
014: //
015: // You should have received a copy of the GNU Lesser General Public
016: // License along with this library; if not, write to the Free Software
017: // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
018: //
019: // -------------
020: // $Id: DataDefinition.java 1988 2007-11-02 11:40:10Z manuel_gay $
021: // $Name$
022: /////////////////////////////////////
023:
024: //TODO extra comments about changes from refactoring
025:
026: package org.makumba;
027:
028: import java.io.Serializable;
029: import java.util.Collection;
030: import java.util.Dictionary;
031: import java.util.Iterator;
032: import java.util.Vector;
033:
034: import org.makumba.commons.StringUtils;
035:
036: /**
037: * Information about a makumba data definition as obtained from an MDD file or the structure of an OQL query result.
038: * This class is provided for makumba programs to be able to introspect makumba data structures. Such introspection is
039: * not needed usually, as the application programmer knows the makumba data structure.
040: */
041: public interface DataDefinition {
042:
043: /** name of this data definition */
044: public String getName();
045:
046: /** the names of the fields declared in this data definition, in the order of declaration */
047: public java.util.Vector getFieldNames();
048:
049: /** the field with the respective name, null if such a field doesn't exist */
050: public FieldDefinition getFieldDefinition(String name);
051:
052: /** the field with the respective index, null if such a field doesn't exist */
053: public FieldDefinition getFieldDefinition(int n);
054:
055: /**
056: * tells whether this data definition was generated temporarily to depict a query result as opposed to being read
057: * from an MDD file
058: */
059: public boolean isTemporary();
060:
061: /** The title field indicated, or the default one */
062: public String getTitleFieldName();
063:
064: /** The name of the index field (primary key), if any? */
065: public String getIndexPointerFieldName();
066:
067: /** The name of the creation timestamp field, if any? */
068: public String getCreationDateFieldName();
069:
070: /** The name of the modification timestamp field, if any? */
071: public String getLastModificationDateFieldName();
072:
073: /**
074: * If this type is the data pointed to by a 1-1 pointer or subset, return the field definition in the main record,
075: * otherwise return null
076: */
077: public FieldDefinition getParentField();
078:
079: /** The name of the set member (Pointer, Character or Integer), for set subtypes */
080: public String getSetMemberFieldName();
081:
082: /** The name of the pointer to the main table, for set and internal set subtypes */
083: public String getSetOwnerFieldName();
084:
085: /** Add a new field definition. Works only for temporary data definitions */
086: public void addField(FieldDefinition fd);
087:
088: /** Checks whether all fieldnames exist in the database */
089: public void checkFieldNames(Dictionary d);
090:
091: /** Checks whether a record can be updated **/
092: public void checkUpdate(String fieldName, Dictionary d);
093:
094: /** Indicates when the data definition was modified the last time */
095: public long lastModified();
096:
097: /** Get the validation definition associated with this data definition. */
098: public ValidationDefinition getValidationDefinition();
099:
100: /** Get all multiple-feld uniqueness definition. */
101: public MultipleUniqueKeyDefinition[] getMultiFieldUniqueKeys();
102:
103: /** Add a multiple-feld uniqueness definition. */
104: public void addMultiUniqueKey(MultipleUniqueKeyDefinition definition);
105:
106: /** Check whether this data definition has a multi-field uniqe key defined with the given fields. */
107: public boolean hasMultiUniqueKey(String[] fieldNames);
108:
109: /** Gets all the fields that are references to other tables, i.e. pointers and some types of sets. */
110: public Vector getReferenceFields();
111:
112: /** Returns the function with the specific name. */
113: public QueryFragmentFunction getFunction(String name);
114:
115: /** adds a new function to this data definition. */
116: public void addFunction(String name, QueryFragmentFunction function);
117:
118: /** returns all functions in this data definition. */
119: public Collection<QueryFragmentFunction> getFunctions();
120:
121: class QueryFragmentFunction implements Serializable {
122: private static final long serialVersionUID = 1L;
123:
124: private String name;
125:
126: private String queryFragment;
127:
128: private DataDefinition parameters;
129:
130: private String errorMessage;
131:
132: public QueryFragmentFunction(String name, String queryFragment,
133: DataDefinition parameters, String errorMessage) {
134: super ();
135: this .name = name;
136: this .queryFragment = queryFragment;
137: this .parameters = parameters;
138: if (errorMessage != null) {
139: this .errorMessage = errorMessage;
140: } else {
141: this .errorMessage = "";
142: }
143: }
144:
145: public String getName() {
146: return name;
147: }
148:
149: public DataDefinition getParameters() {
150: return parameters;
151: }
152:
153: public String getQueryFragment() {
154: return queryFragment;
155: }
156:
157: public String getErrorMessage() {
158: return errorMessage;
159: }
160:
161: @Override
162: public String toString() {
163: String s = "";
164: Vector fieldNames = getParameters().getFieldNames();
165: for (Iterator iter = fieldNames.iterator(); iter.hasNext();) {
166: String name = (String) iter.next();
167: s += getParameters().getFieldDefinition(name).getType()
168: + " " + name;
169: if (iter.hasNext()) {
170: s += ", ";
171: }
172: }
173: s += "";
174: return "QueryFragment Function: " + getName() + "(" + s
175: + ")" + " = " + queryFragment + ":" + errorMessage;
176: }
177:
178: }
179:
180: /** Data structure holding the definition of a mult-field unique key. */
181: class MultipleUniqueKeyDefinition implements Serializable {
182: private static final long serialVersionUID = 1L;
183:
184: private String[] fields;
185:
186: private String line;
187:
188: /** indicates whether this key spans over subfields (internal or external sets, or pointer). */
189: private boolean keyOverSubfield = false;
190:
191: public MultipleUniqueKeyDefinition(String[] fields, String line) {
192: this .fields = fields;
193: this .line = line;
194: }
195:
196: public String[] getFields() {
197: return fields;
198: }
199:
200: public String getLine() {
201: return line;
202: }
203:
204: public void setKeyOverSubfield(boolean keyOverSubfield) {
205: this .keyOverSubfield = keyOverSubfield;
206: }
207:
208: public boolean isKeyOverSubfield() {
209: return keyOverSubfield;
210: }
211:
212: @Override
213: public String toString() {
214: return "Multi-field unique key over: "
215: + StringUtils.toString(fields);
216: }
217:
218: }
219:
220: }
|