001: /*
002:
003: Derby - Class org.apache.derby.tools.URLCheck
004:
005: Licensed to the Apache Software Foundation (ASF) under one or more
006: contributor license agreements. See the NOTICE file distributed with
007: this work for additional information regarding copyright ownership.
008: The ASF licenses this file to You under the Apache License, Version 2.0
009: (the "License"); you may not use this file except in compliance with
010: the License. You may obtain a copy of the License at
011:
012: http://www.apache.org/licenses/LICENSE-2.0
013:
014: Unless required by applicable law or agreed to in writing, software
015: distributed under the License is distributed on an "AS IS" BASIS,
016: WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
017: See the License for the specific language governing permissions and
018: limitations under the License.
019:
020: */
021:
022: package org.apache.derby.tools;
023:
024: import org.apache.derby.iapi.reference.Attribute;
025: import org.apache.derby.iapi.tools.i18n.LocalizedResource;
026: import org.apache.derby.impl.tools.ij.AttributeHolder;
027: import java.util.Vector;
028: import java.util.Properties;
029: import java.util.Enumeration;
030: import java.util.StringTokenizer;
031: import java.lang.reflect.Field;
032: import java.sql.SQLException;
033:
034: /**
035: * This class takes a string used for a connection URL and checks for
036: * correctness.
037: * To turn off output in ij, use the command line
038: * property of -DURLCheck=false.
039: *
040: * param anURL The URL used to connect to a database.
041: *
042: */
043:
044: public class URLCheck {
045:
046: public Vector attributes;
047: public static Vector booleanAttributes;
048: //Need so that AppUI class does not get garbage collected
049: LocalizedResource langUtil = LocalizedResource.getInstance();
050: Vector validProps;
051:
052: public URLCheck(String anURL) {
053:
054: try {
055: //Initialize the AppUI class
056:
057: //Parse the URL string into properties.
058: Properties props = getAttributes(anURL, new Properties());
059: check();
060: } catch (Exception ex) {
061: ex.printStackTrace();
062: }
063: }
064:
065: public static void main(String[] args) {
066: if (args.length > 0) {
067: //Get the first argument passed in.
068: URLCheck aCheck = new URLCheck(args[0]);
069: }
070: }
071:
072: public void check() {
073: Enumeration e = attributes.elements();
074: while (e.hasMoreElements()) {
075: AttributeHolder anAttribute = (AttributeHolder) e
076: .nextElement();
077: //The check for duplicate must be done at the URLCheck level
078: //and not by each specific attribute. Only URLCheck knowns about
079: //all of the attributes and names.
080: checkForDuplicate(anAttribute);
081: //Have each attribute check as much about themself as possible.
082: anAttribute.check(validProps);
083: }
084: }
085:
086: public void checkForDuplicate(AttributeHolder anAttribute) {
087: Enumeration e = attributes.elements();
088: while (e.hasMoreElements()) {
089: AttributeHolder aHolder = (AttributeHolder) e.nextElement();
090: //If a duplicate is found, make sure that the message is only shown
091: //once for each attribute.
092: if (anAttribute != aHolder
093: && anAttribute.getName().equals(aHolder.getName())) {
094: anAttribute.addError(langUtil
095: .getTextMessage("TL_dupAtt"));
096: }
097: }
098:
099: }
100:
101: public Properties getAttributes(String url, Properties props)
102: throws Exception {
103:
104: String protocol = "";
105:
106: if (url.startsWith("jdbc:derby:net:")
107: || url.startsWith("jdbc:derby://")) {
108: validProps = null;
109: } else if (url.startsWith("jdbc:derby:")) {
110: protocol = "jdbc:derby:";
111: validProps = getValidDerbyProps();
112: } else
113: validProps = null;
114:
115: //Parse the url into attributes and put them in a Properties object.
116: StringTokenizer st = new StringTokenizer(url.substring(protocol
117: .length()), ";:\"");
118: attributes = new Vector();
119: while (st.hasMoreTokens()) {
120: AttributeHolder anAttribute = new AttributeHolder();
121: String anAtt = "";
122: String aValue = "";
123: String aToken = st.nextToken();
124: //The "=" is the seperator between key and value.
125: int eqPos = aToken.indexOf('=');
126: if (eqPos == -1) {
127: //If there is no "=" this is not an attribute
128: continue;
129: } else {
130: anAtt = (aToken.substring(0, eqPos)).trim();
131: aValue = (aToken.substring(eqPos + 1)).trim();
132:
133: }
134: anAttribute.setName(anAtt);
135: anAttribute.setValue(aValue);
136: anAttribute.setToken(aToken);
137: attributes.addElement(anAttribute);
138: props.put(anAtt, aToken);
139: }
140: return props;
141: }
142:
143: public static Vector getBooleanAttributes() {
144: if (booleanAttributes == null) {
145: booleanAttributes = new Vector();
146: booleanAttributes.addElement(Attribute.DATA_ENCRYPTION);
147: booleanAttributes.addElement(Attribute.CREATE_ATTR);
148: booleanAttributes.addElement(Attribute.SHUTDOWN_ATTR);
149: booleanAttributes.addElement(Attribute.UPGRADE_ATTR);
150: }
151: return booleanAttributes;
152: }
153:
154: private static Vector validDerbyProps;
155:
156: private Vector getValidDerbyProps() {
157: if (validDerbyProps == null) {
158: try {
159: Vector props = new Vector();
160: Class att = Attribute.class;
161: //Use reflection to get the list of valid keys from the Attribute class.
162: //The Attribute class is an interface and therefore all the field
163: //for it are public.
164: Field[] fields = att.getFields();
165: for (int i = 0; i < fields.length; i++) {
166: Field aField = (Field) fields[i];
167: props.addElement(aField.get(att));
168: }
169: validDerbyProps = props;
170: } catch (Exception ex) {
171: ex.printStackTrace();
172: }
173: }
174: return validDerbyProps;
175: } // end of getValidDerbyProps
176:
177: }
|