001: /*
002: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
003: *
004: * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
005: *
006: * The contents of this file are subject to the terms of either the GNU
007: * General Public License Version 2 only ("GPL") or the Common
008: * Development and Distribution License("CDDL") (collectively, the
009: * "License"). You may not use this file except in compliance with the
010: * License. You can obtain a copy of the License at
011: * http://www.netbeans.org/cddl-gplv2.html
012: * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
013: * specific language governing permissions and limitations under the
014: * License. When distributing the software, include this License Header
015: * Notice in each file and include the License file at
016: * nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this
017: * particular file as subject to the "Classpath" exception as provided
018: * by Sun in the GPL Version 2 section of the License file that
019: * accompanied this code. If applicable, add the following below the
020: * License Header, with the fields enclosed by brackets [] replaced by
021: * your own identifying information:
022: * "Portions Copyrighted [year] [name of copyright owner]"
023: *
024: * Contributor(s):
025: *
026: * The Original Software is NetBeans. The Initial Developer of the Original
027: * Software is Sun Microsystems, Inc. Portions Copyright 1997-2007 Sun
028: * Microsystems, Inc. All Rights Reserved.
029: *
030: * If you wish your version of this file to be governed by only the CDDL
031: * or only the GPL Version 2, indicate your decision by adding
032: * "[Contributor] elects to include this software in this distribution
033: * under the [CDDL or GPL Version 2] license." If you do not indicate a
034: * single choice of license, a recipient has the option to distribute
035: * your version of this file under either the CDDL, the GPL Version 2 or
036: * to extend the choice of license to its licensees as provided above.
037: * However, if you add GPL Version 2 code and therefore, elected the GPL
038: * Version 2 license, then the option applies only if the new code is
039: * made subject to such option by the copyright holder.
040: */
041:
042: package org.netbeans.modules.sql.framework.codegen;
043:
044: import java.util.ArrayList;
045: import java.util.HashMap;
046: import java.util.Iterator;
047: import java.util.List;
048: import java.util.ListIterator;
049: import java.util.Map;
050: import org.netbeans.modules.sql.framework.common.jdbc.SQLUtils;
051: import org.netbeans.modules.sql.framework.common.utils.TagParserUtility;
052: import org.netbeans.modules.sql.framework.model.SQLConstants;
053: import org.netbeans.modules.sql.framework.model.SQLOperatorArg;
054: import org.netbeans.modules.sql.framework.model.SQLOperatorDefinition;
055: import org.w3c.dom.Element;
056: import org.w3c.dom.NodeList;
057: import com.sun.sql.framework.exception.BaseException;
058: import com.sun.sql.framework.utils.Attribute;
059: import com.sun.sql.framework.utils.StringUtil;
060:
061: /**
062: *
063: * Holds an Operator Instance:
064: * Modified from a static inner class to a public class as the usage of this class
065: * has changed. Its no longer a holder for the operator definition templates but also
066: * to represent the custom operator instances.
067: *
068: * @author Jonathan Giron
069: * @author Ahimanikya Satapathy
070: */
071: public class OperatorInstance implements SQLOperatorDefinition {
072:
073: /* Argument list */
074: private List<SQLOperatorArg> argList;
075: /* Output type list. */
076: private List<String> outputTypeList;
077: /* Operator name. */
078: private String operatorName;
079: /* Holds SQL script as text representation of operator */
080: private String script;
081: /*
082: * Database specfic operator name. Used by javacc parser, this should be name user
083: * types in sql editor
084: */
085: private String dbSpecficName;
086: /* GUI name of the operator */
087: private String guiName;
088: /* type of operator category (numeric or string) */
089: private String operatorCategoryType;
090: /* argument to use while calculating precision and scale. */
091: private List arg2UseList;
092: private Map attributes = new HashMap();
093: /* Constant for name attribute. */
094: private static final String ATTR_NAME = "name";
095: /* Attribute name for operator type string. */
096: private static final String ATTR_TYPE = "type";
097: /* Attribute name for argument to use while calculating precision and scale */
098: private static final String ATTR_ARG2USE = "arg2Use";
099: /* Child node tag name for output tag. */
100: private static final String TAG_OUTPUT = "output";
101: /* Attribute name for operator script string. */
102: private static final String ATTR_SCRIPT = "script";
103: private static final String ATTR_DBSPECFICNAME = "dbspecificname";
104: private static final String ATTR_GUINAME = "guiname";
105: /* Child node tag name for argument tag. */
106: private static final String TAG_ARG = "arg";
107: /* Constant for operator defn metadata tag. */
108: private static final String TAG_OPERATOR = "operator";
109: private static final String ATTR_RANGE = "range";
110:
111: /**
112: * Constructs a default instance of OperatorInstance.
113: */
114: public OperatorInstance() {
115: argList = new ArrayList<SQLOperatorArg>();
116: outputTypeList = new ArrayList<String>();
117: }
118:
119: /**
120: * Constructs a new instance of OperatorInstance with the given operator name.
121: *
122: * @param newName operator name
123: */
124: public OperatorInstance(String newName) {
125: this ();
126: operatorName = newName;
127: }
128:
129: /**
130: * @see SQLObject#getAttributeObject
131: */
132: public Object getAttributeValue(String attrName) {
133: Attribute attr = getAttribute(attrName);
134: return (attr != null) ? attr.getAttributeValue() : null;
135: }
136:
137: /**
138: * Gets an attribute based on its name.
139: *
140: * @param attrName attribute Name
141: * @return Attribute instance associated with attrName, or null if none exists
142: */
143: public Attribute getAttribute(String attrName) {
144: return (Attribute) attributes.get(attrName);
145: }
146:
147: /**
148: * Get the number of input arguments defined in the script. If the operator script
149: * defines an operator with variable number of arguments then we allow a maximum
150: * of 100 input arguments.
151: *
152: * @return maximum number of arguments this operator can support.
153: */
154: public int getArgCount() {
155: if (script == null) {
156: return 0;
157: } else if (script.indexOf("[") == -1) {
158: return argList.size();
159: } else {
160: return SQLConstants.MAX_SCRIPT_ARGUMENT_COUNT;
161: }
162: }
163:
164: /**
165: * Indicates if this operator can take a variable number of input arguments.
166: *
167: * @return flag indicating weather this operator takes variable number of input
168: * arguments.
169: */
170: public int getArgCountType() {
171: if (this .script.indexOf("[") == -1) {
172: return SQLConstants.OPERATOR_ARGS_FIXED;
173: }
174: return SQLConstants.OPERATOR_ARGS_VARIABLE;
175: }
176:
177: /**
178: * @see SQLOperatorDefinition#getVarOperatorArgName
179: */
180: public String getVarOperatorArgName() {
181: SQLOperatorArg arg = argList.get(0);
182: return arg.getArgName();
183: }
184:
185: /**
186: * @see SQLOperatorDefinition#getArgIndex(java.lang.String)
187: */
188: public int getArgIndex(String argName) {
189: if (argList == null || argName == null) {
190: return -1;
191: }
192:
193: ListIterator iter = argList.listIterator();
194: while (iter.hasNext()) {
195: SQLOperatorArg arg = (SQLOperatorArg) iter.next();
196: if (argName.equals(arg.getArgName())) {
197: return iter.previousIndex();
198: }
199: }
200:
201: return -1;
202: }
203:
204: /**
205: * @see SQLOperatorDefinition#getArgList
206: */
207: public List getArgList() {
208: return argList;
209: }
210:
211: /**
212: * @see SQLOperatorDefinition#setArgList(List)
213: */
214: public void setArgList(List<SQLOperatorArg> args) {
215: this .argList = args;
216: }
217:
218: /**
219: * @see SQLOperatorDefinition#getArgType(int)
220: */
221: public String getArgType(int i) {
222: SQLOperatorArg operatorArg = argList.get(i);
223: return SQLUtils.getStdSqlType(operatorArg.getJdbcType());
224: }
225:
226: /**
227: * @see SQLOperatorDefinition#getArgJdbcSQLType(int)
228: */
229: public int getArgJdbcSQLType(int i) {
230: if (i < argList.size()) {
231: SQLOperatorArg operatorArg = argList.get(i);
232: return operatorArg.getJdbcType();
233: }
234: return SQLConstants.JDBCSQL_TYPE_UNDEFINED;
235: }
236:
237: /**
238: * @see SQLOperatorDefinition#getArgJdbcSQLType(java.lang.String)
239: */
240: public int getArgJdbcSQLType(String argName) {
241: if (argName != null) {
242: Iterator it = argList.iterator();
243:
244: while (it.hasNext()) {
245: SQLOperatorArg operatorArg = (SQLOperatorArg) it.next();
246: if (operatorArg.getArgName().equals(argName)) {
247: return operatorArg.getJdbcType();
248: }
249: }
250: }
251: return SQLConstants.JDBCSQL_TYPE_UNDEFINED;
252: }
253:
254: /**
255: * Gets the range based on argname.
256: *
257: * @param argName for which range is returned
258: * @return String for range
259: */
260: public String getRange(String argName) {
261: if (argName != null) {
262: Iterator it = argList.iterator();
263:
264: while (it.hasNext()) {
265: SQLOperatorArg operatorArg = (SQLOperatorArg) it.next();
266: if (operatorArg.getArgName().equals(argName)) {
267: return operatorArg.getRange();
268: }
269: }
270: }
271: return null;
272: }
273:
274: /**
275: * @see SQLOperatorDefinition#getOperatorName
276: */
277: public String getOperatorName() {
278: return this .operatorName;
279: }
280:
281: /**
282: * @see SQLOperatorDefinition#getOperatorName
283: */
284: public void setOperatorName(String anOperatorName) {
285: this .operatorName = anOperatorName;
286: }
287:
288: /**
289: * Get DB-specific name
290: *
291: * @return DB-specific name
292: */
293: public String getDbSpecficName() {
294: return this .dbSpecficName;
295: }
296:
297: /**
298: * @see org.netbeans.modules.sql.framework.model.SQLOperatorDefinition#getGuiName()
299: */
300: public String getGuiName() {
301: String gName = this .guiName;
302: if (gName == null || gName.trim().equals("")) {
303: return getScript();
304: }
305:
306: return gName;
307: }
308:
309: /**
310: * @see SQLOperatorDefinition#getScript
311: */
312: public String getScript() {
313: return script;
314: }
315:
316: /**
317: * @see SQLOperatorDefinition
318: */
319: public void setScript(String aScript) {
320: this .script = aScript;
321: }
322:
323: /**
324: * @see SQLOperatorDefinition#addArg
325: */
326: public boolean addArg(SQLOperatorArg operatorArg) {
327: if (operatorArg.getArgName() != null
328: && SQLUtils.getStdSqlType(operatorArg.getJdbcType()) != null) {
329: argList.add(operatorArg);
330: return true;
331: }
332: return false;
333: }
334:
335: /**
336: * @see SQLOperatorDefinition#getOperatorArg
337: */
338: public SQLOperatorArg getOperatorArg(int index) {
339: return this .argList.get(index);
340: }
341:
342: /**
343: * @see SQLOperatorDefinition#addOutputType
344: */
345: public boolean addOutputType(String outputType) {
346: if (outputType != null) {
347: outputTypeList.add(outputType);
348: return true;
349: }
350: return false;
351: }
352:
353: /**
354: * @see SQLOperatorDefinition#getOutputJdbcSQLType
355: */
356: public int getOutputJdbcSQLType() {
357: if (outputTypeList.size() == 1) {
358: return SQLUtils.getStdJdbcType(outputTypeList.get(0));
359: }
360: return SQLConstants.JDBCSQL_TYPE_UNDEFINED;
361: }
362:
363: /**
364: * sets the jdbc type of this operators return type
365: * @param int jdbcType sql constant for the type
366: */
367: public void setOutputJdbcSQLType(int i) {
368: outputTypeList.add(SQLUtils.getStdSqlType(i));
369: }
370:
371: /**
372: * This method is another convenience method to compute
373: * the sql constant for the given string and set the jdbc type
374: * sets the jdbc type of this operators return type
375: * @param String jdbcType
376: */
377: public void setOutputJdbcSQLType(String jdbcType) {
378: outputTypeList.add(jdbcType);
379: }
380:
381: /**
382: * @see SQLOperatorDefinition#parseXML(org.w3c.dom.Element)
383: */
384: public void parseXML(Element defnElement) throws BaseException {
385: if (defnElement == null
386: || !TAG_OPERATOR.equals(defnElement.getNodeName())) {
387: throw new BaseException(
388: "Must supply non-null Element of type "
389: + TAG_OPERATOR + ".");
390: }
391:
392: NodeList argNodeList;
393: NodeList outputTypeNodeList;
394: NodeList attributeList;
395:
396: operatorName = defnElement.getAttribute(ATTR_NAME);
397: dbSpecficName = defnElement.getAttribute(ATTR_DBSPECFICNAME);
398: guiName = defnElement.getAttribute(ATTR_GUINAME);
399:
400: script = defnElement.getAttribute(ATTR_SCRIPT);
401: operatorCategoryType = defnElement.getAttribute(ATTR_TYPE);
402: String arg2Use = defnElement.getAttribute(ATTR_ARG2USE);
403: arg2UseList = StringUtil.createStringListFrom(arg2Use);
404:
405: attributeList = defnElement
406: .getElementsByTagName(Attribute.TAG_ATTR);
407: TagParserUtility.parseAttributeList(attributes, attributeList);
408:
409: argNodeList = defnElement.getElementsByTagName(TAG_ARG);
410: for (int j = 0; j < argNodeList.getLength(); j++) {
411: Element argElement;
412: String arg;
413: String argType;
414: argElement = (Element) argNodeList.item(j);
415: arg = argElement.getAttribute(ATTR_NAME);
416: argType = argElement.getAttribute(ATTR_TYPE);
417:
418: String range = argElement.getAttribute(ATTR_RANGE);
419: SQLOperatorArg operatorArg = new SQLOperatorArg(arg,
420: SQLUtils.getStdJdbcType(argType));
421: addArg(operatorArg);
422:
423: if (!StringUtil.isNullString(range)) {
424: operatorArg.setRange(range);
425: }
426: }
427: outputTypeNodeList = defnElement
428: .getElementsByTagName(TAG_OUTPUT);
429:
430: for (int k = 0; k < outputTypeNodeList.getLength(); k++) {
431: String type;
432: Element outputElement;
433:
434: outputElement = (Element) outputTypeNodeList.item(k);
435: type = outputElement.getAttribute(ATTR_TYPE);
436: addOutputType(type);
437: }
438: }
439:
440: /**
441: * @see org.netbeans.modules.sql.framework.model.SQLOperatorDefinition#getArg2Use()
442: */
443: public List getArg2Use() {
444: return this .arg2UseList;
445: }
446:
447: /**
448: * @see org.netbeans.modules.sql.framework.model.SQLOperatorDefinition#getOperatorCategoryType()
449: */
450: public String getOperatorCategoryType() {
451: return this .operatorCategoryType;
452: }
453:
454: public Object clone(List operatorArgs) {
455: try {
456: return this .clone();
457: } catch (CloneNotSupportedException ex) {
458: ex.printStackTrace();
459: }
460: return null;
461: }
462: }
|