1 | /* |
2 | |
3 | Derby - Class org.apache.derby.tools.URLCheck |
4 | |
5 | Copyright 2000, 2004 The Apache Software Foundation or its licensors, as applicable. |
6 | |
7 | Licensed under the Apache License, Version 2.0 (the "License"); |
8 | you may not use this file except in compliance with the License. |
9 | You may obtain a copy of the License at |
10 | |
11 | http://www.apache.org/licenses/LICENSE-2.0 |
12 | |
13 | Unless required by applicable law or agreed to in writing, software |
14 | distributed under the License is distributed on an "AS IS" BASIS, |
15 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
16 | See the License for the specific language governing permissions and |
17 | limitations under the License. |
18 | |
19 | */ |
20 | |
21 | package org.apache.derby.tools; |
22 | |
23 | import org.apache.derby.iapi.reference.Attribute; |
24 | import org.apache.derby.iapi.tools.i18n.LocalizedResource; |
25 | import org.apache.derby.impl.tools.ij.AttributeHolder; |
26 | import java.util.Vector; |
27 | import java.util.Properties; |
28 | import java.util.Enumeration; |
29 | import java.util.StringTokenizer; |
30 | import java.lang.reflect.Field; |
31 | import java.sql.SQLException; |
32 | |
33 | /** |
34 | * This class takes a string used for a connection URL and checks for |
35 | * correctness. |
36 | * To turn off output in ij, use the command line |
37 | * property of -DURLCheck=false. |
38 | * |
39 | * param anURL The URL used to connect to a database. |
40 | * |
41 | */ |
42 | |
43 | public class URLCheck { |
44 | |
45 | public Vector attributes; |
46 | public static Vector booleanAttributes; |
47 | //Need so that AppUI class does not get garbage collected |
48 | LocalizedResource langUtil = LocalizedResource.getInstance(); |
49 | Vector validProps; |
50 | |
51 | public URLCheck(String anURL) { |
52 | |
53 | try { |
54 | //Initialize the AppUI class |
55 | |
56 | //Parse the URL string into properties. |
57 | Properties props = getAttributes(anURL, new Properties()); |
58 | check(); |
59 | } |
60 | catch (Exception ex) { |
61 | ex.printStackTrace(); |
62 | } |
63 | } |
64 | |
65 | |
66 | public static void main(String[] args) { |
67 | if (args.length > 0) { |
68 | //Get the first argument passed in. |
69 | URLCheck aCheck = new URLCheck(args[0]); |
70 | } |
71 | } |
72 | public void check(){ |
73 | Enumeration e = attributes.elements(); |
74 | while (e.hasMoreElements()) { |
75 | AttributeHolder anAttribute = (AttributeHolder)e.nextElement(); |
76 | //The check for duplicate must be done at the URLCheck level |
77 | //and not by each specific attribute. Only URLCheck knowns about |
78 | //all of the attributes and names. |
79 | checkForDuplicate(anAttribute); |
80 | //Have each attribute check as much about themself as possible. |
81 | anAttribute.check( validProps); |
82 | } |
83 | } |
84 | public void checkForDuplicate(AttributeHolder anAttribute){ |
85 | Enumeration e = attributes.elements(); |
86 | while (e.hasMoreElements()) { |
87 | AttributeHolder aHolder = (AttributeHolder)e.nextElement(); |
88 | //If a duplicate is found, make sure that the message is only shown |
89 | //once for each attribute. |
90 | if (anAttribute != aHolder && anAttribute.getName().equals(aHolder.getName())) { |
91 | anAttribute.addError(langUtil.getTextMessage("TL_dupAtt")); |
92 | } |
93 | } |
94 | |
95 | } |
96 | public Properties getAttributes(String url, Properties props) throws Exception { |
97 | |
98 | String protocol = ""; |
99 | |
100 | if( url.startsWith( "jdbc:derby:net:") || |
101 | url.startsWith( "jdbc:derby://")) |
102 | { |
103 | validProps = null; |
104 | } |
105 | else if( url.startsWith( "jdbc:derby:")) |
106 | { |
107 | protocol = "jdbc:derby:"; |
108 | validProps = getValidDerbyProps(); |
109 | } |
110 | else |
111 | validProps = null; |
112 | |
113 | |
114 | //Parse the url into attributes and put them in a Properties object. |
115 | StringTokenizer st = new StringTokenizer(url.substring(protocol.length()), ";:\""); |
116 | attributes = new Vector(); |
117 | while (st.hasMoreTokens()) { |
118 | AttributeHolder anAttribute = new AttributeHolder(); |
119 | String anAtt = ""; |
120 | String aValue = ""; |
121 | String aToken = st.nextToken(); |
122 | //The "=" is the seperator between key and value. |
123 | int eqPos = aToken.indexOf('='); |
124 | if (eqPos == -1) { |
125 | //If there is no "=" this is not an attribute |
126 | continue; |
127 | } |
128 | else { |
129 | anAtt = (aToken.substring(0, eqPos)).trim(); |
130 | aValue = (aToken.substring(eqPos + 1)).trim(); |
131 | |
132 | } |
133 | anAttribute.setName(anAtt); |
134 | anAttribute.setValue(aValue); |
135 | anAttribute.setToken(aToken); |
136 | attributes.addElement(anAttribute); |
137 | props.put(anAtt, aToken); |
138 | } |
139 | return props; |
140 | } |
141 | |
142 | public static Vector getBooleanAttributes(){ |
143 | if (booleanAttributes == null) { |
144 | booleanAttributes = new Vector(); |
145 | booleanAttributes.addElement(Attribute.DATA_ENCRYPTION); |
146 | booleanAttributes.addElement(Attribute.CREATE_ATTR); |
147 | booleanAttributes.addElement(Attribute.SHUTDOWN_ATTR); |
148 | booleanAttributes.addElement(Attribute.UPGRADE_ATTR); |
149 | } |
150 | return booleanAttributes; |
151 | } |
152 | |
153 | private static Vector validDerbyProps; |
154 | private Vector getValidDerbyProps() |
155 | { |
156 | if( validDerbyProps == null) |
157 | { |
158 | try |
159 | { |
160 | Vector props = new Vector(); |
161 | Class att = Attribute.class; |
162 | //Use reflection to get the list of valid keys from the Attribute class. |
163 | //The Attribute class is an interface and therefore all the field |
164 | //for it are public. |
165 | Field[] fields = att.getFields(); |
166 | for (int i = 0; i < fields.length; i++) |
167 | { |
168 | Field aField = (Field)fields[i]; |
169 | props.addElement(aField.get(att)); |
170 | } |
171 | validDerbyProps = props; |
172 | } |
173 | catch (Exception ex) |
174 | { |
175 | ex.printStackTrace(); |
176 | } |
177 | } |
178 | return validDerbyProps; |
179 | } // end of getValidDerbyProps |
180 | |
181 | } |