001: /**
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: */package org.apache.geronimo.gbean;
017:
018: import java.io.Serializable;
019: import java.net.URI;
020: import java.net.URISyntaxException;
021: import java.util.ArrayList;
022: import java.util.Collections;
023: import java.util.Iterator;
024: import java.util.List;
025: import java.util.Map;
026: import java.util.TreeMap;
027: import javax.management.ObjectName;
028:
029: import org.apache.geronimo.kernel.repository.Artifact;
030: import org.apache.geronimo.kernel.Jsr77Naming;
031:
032: /**
033: * @version $Rev: 476049 $ $Date: 2006-11-16 20:35:17 -0800 (Thu, 16 Nov 2006) $
034: */
035: public class AbstractName implements Serializable {
036: private static final long serialVersionUID = 3584199042821734754L;
037:
038: private final Artifact artifact;
039: private final Map name;
040: private final ObjectName objectName;
041: private final URI uri;
042:
043: public AbstractName(Artifact artifact, Map name) {
044: if (artifact == null)
045: throw new NullPointerException("artifact is null");
046: if (name == null)
047: throw new NullPointerException("name is null");
048: if (name.isEmpty())
049: throw new IllegalArgumentException("name is empty");
050:
051: this .artifact = artifact;
052: this .name = name;
053:
054: this .objectName = Jsr77Naming.createObjectName(name);
055:
056: this .uri = createURI(artifact, name);
057: }
058:
059: public AbstractName(Artifact artifact, Map name,
060: ObjectName objectName) {
061: if (artifact == null)
062: throw new NullPointerException("artifact is null");
063: if (name == null)
064: throw new NullPointerException("name is null");
065: if (name.isEmpty())
066: throw new IllegalArgumentException("name is empty");
067: if (objectName == null)
068: throw new NullPointerException("objectName is null");
069:
070: this .artifact = artifact;
071: this .name = name;
072: this .objectName = objectName;
073:
074: this .uri = createURI(artifact, name);
075: }
076:
077: /**
078: * Contructs an AbstractName object from the given URI.
079: *
080: * The artifactId for the AbstractName is constructed from the URI path
081: * (everything up to the ? character) and is composed of four parts delimited by
082: * slashes. The artifactId is the only mandatory part, all slashes are mandatory.
083: *
084: * The name map for the AbstractName is constructed from key=value pairs.
085: * Each key=value pair is delimited by a ',' character and the key is separated
086: * from the value by the '=' character. Each key must be unique.
087: * At least one key=value pair must be specified in the query string.
088: *
089: * The URI has the following format:
090: * [vendorId]/artifactId/[version]/[type]?key=value[,key=value][,...]
091: *
092: * @param uri The URI to be used to generate an AbstractName.
093: */
094: public AbstractName(URI uri) {
095: if (uri == null)
096: throw new NullPointerException("uri is null");
097:
098: //
099: // Artifact
100: //
101: String artifactString = uri.getPath();
102: if (artifactString == null)
103: throw new IllegalArgumentException(
104: "uri does not contain a path part used for the artifact");
105:
106: List artifactParts = split(artifactString, '/');
107: if (artifactParts.size() != 4) {
108: throw new IllegalArgumentException(
109: "uri path must be in the form [vendorId]/artifactId/[version]/[type] : "
110: + artifactString);
111: }
112:
113: String groupId = (String) artifactParts.get(0);
114: if (groupId.length() == 0)
115: groupId = null;
116:
117: String artifactId = (String) artifactParts.get(1);
118: if (artifactId.length() == 0)
119: artifactId = null;
120:
121: String version = (String) artifactParts.get(2);
122: if (version.length() == 0)
123: version = null;
124:
125: String type = (String) artifactParts.get(3);
126: if (type.length() == 0)
127: type = null;
128:
129: artifact = new Artifact(groupId, artifactId, version, type);
130:
131: //
132: // name map
133: //
134: name = new TreeMap();
135: String nameString = uri.getQuery();
136: if (nameString == null)
137: throw new IllegalArgumentException(
138: "uri does not contain a query part used for the name map");
139: List nameParts = split(nameString, ',');
140: for (Iterator iterator = nameParts.iterator(); iterator
141: .hasNext();) {
142: String namePart = (String) iterator.next();
143: List keyValue = split(namePart, '=');
144: if (keyValue.size() != 2) {
145: throw new IllegalArgumentException(
146: "uri query string must be in the form ?key=value[,key=value]*] : "
147: + nameString);
148: }
149: String key = (String) keyValue.get(0);
150: String value = (String) keyValue.get(1);
151: if (name.containsKey(key)) {
152: throw new IllegalArgumentException(
153: "uri query string contains the key '" + key
154: + "' twice : " + nameString);
155: }
156: name.put(key, value);
157: }
158: if (name.isEmpty()) {
159: throw new IllegalArgumentException("name is empty: "
160: + nameString);
161: }
162:
163: //
164: // uri
165: //
166: this .uri = createURI(artifact, name);
167:
168: //
169: // object name
170: //
171: this .objectName = Jsr77Naming.createObjectName(name);
172: }
173:
174: private static URI createURI(Artifact artifact, Map name) {
175: StringBuffer queryString = new StringBuffer();
176: TreeMap treeMap = new TreeMap(name);
177: for (Iterator iterator = treeMap.entrySet().iterator(); iterator
178: .hasNext();) {
179: Map.Entry entry = (Map.Entry) iterator.next();
180: String key = (String) entry.getKey();
181: String value = (String) entry.getValue();
182: queryString.append(key).append('=').append(value);
183: if (iterator.hasNext()) {
184: queryString.append(',');
185: }
186: }
187: try {
188: return new URI(null, null, artifact.toString(), queryString
189: .toString(), null);
190: } catch (URISyntaxException e) {
191: IllegalArgumentException illegalArgumentException = new IllegalArgumentException();
192: illegalArgumentException.initCause(e);
193: throw illegalArgumentException;
194: }
195: }
196:
197: // why not use String.split? Because String.split works using regular expressions
198: // and this should be way faster, but write a benchmark it out if you have time.
199: // Also this code is way simpler.
200: private static List split(String source, char delim) {
201: List parts = new ArrayList();
202: for (int index = source.indexOf(delim); index >= 0; index = source
203: .indexOf(delim)) {
204: String part = source.substring(0, index);
205: source = source.substring(index + 1);
206: parts.add(part);
207: }
208: parts.add(source);
209: return parts;
210: }
211:
212: public Artifact getArtifact() {
213: return artifact;
214: }
215:
216: public Map getName() {
217: return Collections.unmodifiableMap(name);
218: }
219:
220: public String getNameProperty(String key) {
221: return (String) name.get(key);
222: }
223:
224: public ObjectName getObjectName() {
225: return objectName;
226: }
227:
228: public URI toURI() {
229: return uri;
230: }
231:
232: public String toString() {
233: return uri.toString();
234: }
235:
236: public boolean equals(Object o) {
237: if (this == o)
238: return true;
239: if (o == null || getClass() != o.getClass())
240: return false;
241:
242: final AbstractName that = (AbstractName) o;
243:
244: if (artifact != null ? !artifact.equals(that.artifact)
245: : that.artifact != null)
246: return false;
247: return !(name != null ? !name.equals(that.name)
248: : that.name != null);
249:
250: }
251:
252: public int hashCode() {
253: int result;
254: result = (artifact != null ? artifact.hashCode() : 0);
255: result = 29 * result + (name != null ? name.hashCode() : 0);
256: return result;
257: }
258:
259: }
|