1 /**
2 *
3 * Copyright 2006 The Apache Software Foundation
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17
18 package org.apache.geronimo.gbean;
19
20 import java.io.Serializable;
21 import java.net.URI;
22 import java.net.URISyntaxException;
23 import java.util.ArrayList;
24 import java.util.Collections;
25 import java.util.Iterator;
26 import java.util.List;
27 import java.util.Map;
28 import java.util.TreeMap;
29 import javax.management.ObjectName;
30
31 import org.apache.geronimo.kernel.repository.Artifact;
32 import org.apache.geronimo.kernel.Jsr77Naming;
33
34 /**
35 * @version $Rev: 430508 $ $Date: 2006-08-10 12:56:47 -0700 (Thu, 10 Aug 2006) $
36 */
37 public class AbstractName implements Serializable {
38 private static final long serialVersionUID = 3584199042821734754L;
39
40 private final Artifact artifact;
41 private final Map name;
42 private final ObjectName objectName;
43 private final URI uri;
44
45 public AbstractName(Artifact artifact, Map name) {
46 if (artifact == null) throw new NullPointerException("artifact is null");
47 if (name == null) throw new NullPointerException("name is null");
48 if (name.isEmpty()) throw new IllegalArgumentException("name is empty");
49
50 this.artifact = artifact;
51 this.name = name;
52
53 this.objectName = Jsr77Naming.createObjectName(name);
54
55 this.uri = createURI(artifact, name);
56 }
57
58 public AbstractName(Artifact artifact, Map name, ObjectName objectName) {
59 if (artifact == null) throw new NullPointerException("artifact is null");
60 if (name == null) throw new NullPointerException("name is null");
61 if (name.isEmpty()) throw new IllegalArgumentException("name is empty");
62 if (objectName == null) throw new NullPointerException("objectName is null");
63
64 this.artifact = artifact;
65 this.name = name;
66 this.objectName = objectName;
67
68 this.uri = createURI(artifact, name);
69 }
70
71 /**
72 * Contructs an AbstractName object from the given URI.
73 *
74 * The artifactId for the AbstractName is constructed from the URI path
75 * (everything up to the ? character) and is composed of four parts delimited by
76 * slashes. The artifactId is the only mandatory part, all slashes are mandatory.
77 *
78 * The name map for the AbstractName is constructed from key=value pairs.
79 * Each key=value pair is delimited by a ',' character and the key is separated
80 * from the value by the '=' character. Each key must be unique.
81 * At least one key=value pair must be specified in the query string.
82 *
83 * The URI has the following format:
84 * [vendorId]/artifactId/[version]/[type]?key=value[,key=value][,...]
85 *
86 * @param uri The URI to be used to generate an AbstractName.
87 */
88 public AbstractName(URI uri) {
89 if (uri == null) throw new NullPointerException("uri is null");
90
91
92
93
94 String artifactString = uri.getPath();
95 if (artifactString == null) throw new IllegalArgumentException("uri does not contain a path part used for the artifact");
96
97 List artifactParts = split(artifactString, '/');
98 if (artifactParts.size() != 4) {
99 throw new IllegalArgumentException("uri path must be in the form [vendorId]/artifactId/[version]/[type] : " + artifactString);
100 }
101
102 String groupId = (String) artifactParts.get(0);
103 if (groupId.length() == 0) groupId = null;
104
105 String artifactId = (String) artifactParts.get(1);
106 if (artifactId.length() == 0) artifactId = null;
107
108 String version = (String) artifactParts.get(2);
109 if (version.length() == 0) version = null;
110
111 String type = (String) artifactParts.get(3);
112 if (type.length() == 0) type = null;
113
114 artifact = new Artifact(groupId, artifactId, version, type);
115
116
117
118
119 name = new TreeMap();
120 String nameString = uri.getQuery();
121 if (nameString == null) throw new IllegalArgumentException("uri does not contain a query part used for the name map");
122 List nameParts = split(nameString, ',');
123 for (Iterator iterator = nameParts.iterator(); iterator.hasNext();) {
124 String namePart = (String) iterator.next();
125 List keyValue = split(namePart, '=');
126 if (keyValue.size() != 2) {
127 throw new IllegalArgumentException("uri query string must be in the form ?key=value[,key=value]*] : " + nameString);
128 }
129 String key = (String) keyValue.get(0);
130 String value = (String) keyValue.get(1);
131 if (name.containsKey(key)) {
132 throw new IllegalArgumentException("uri query string contains the key '"+ key + "' twice : " + nameString);
133 }
134 name.put(key, value);
135 }
136 if (name.isEmpty()) {
137 throw new IllegalArgumentException("name is empty: " + nameString);
138 }
139
140
141
142
143 this.uri = createURI(artifact, name);
144
145
146
147
148 this.objectName = Jsr77Naming.createObjectName(name);
149 }
150
151 private static URI createURI(Artifact artifact, Map name) {
152 StringBuffer queryString = new StringBuffer();
153 TreeMap treeMap = new TreeMap(name);
154 for (Iterator iterator = treeMap.entrySet().iterator(); iterator.hasNext();) {
155 Map.Entry entry = (Map.Entry) iterator.next();
156 String key = (String) entry.getKey();
157 String value = (String) entry.getValue();
158 queryString.append(key).append('=').append(value);
159 if (iterator.hasNext()) {
160 queryString.append(',');
161 }
162 }
163 try {
164 return new URI(null, null, artifact.toString(), queryString.toString(), null);
165 } catch (URISyntaxException e) {
166 IllegalArgumentException illegalArgumentException = new IllegalArgumentException();
167 illegalArgumentException.initCause(e);
168 throw illegalArgumentException;
169 }
170 }
171
172
173
174
175 private static List split(String source, char delim) {
176 List parts = new ArrayList();
177 for (int index = source.indexOf(delim); index >= 0; index = source.indexOf(delim)) {
178 String part = source.substring(0, index);
179 source = source.substring(index + 1);
180 parts.add(part);
181 }
182 parts.add(source);
183 return parts;
184 }
185
186 public Artifact getArtifact() {
187 return artifact;
188 }
189
190 public Map getName() {
191 return Collections.unmodifiableMap(name);
192 }
193
194 public String getNameProperty(String key) {
195 return (String) name.get(key);
196 }
197
198 public ObjectName getObjectName() {
199 return objectName;
200 }
201
202 public URI toURI() {
203 return uri;
204 }
205
206 public String toString() {
207 return uri.toString();
208 }
209
210 public boolean equals(Object o) {
211 if (this == o) return true;
212 if (o == null || getClass() != o.getClass()) return false;
213
214 final AbstractName that = (AbstractName) o;
215
216 if (artifact != null ? !artifact.equals(that.artifact) : that.artifact != null) return false;
217 return !(name != null ? !name.equals(that.name) : that.name != null);
218
219 }
220
221 public int hashCode() {
222 int result;
223 result = (artifact != null ? artifact.hashCode() : 0);
224 result = 29 * result + (name != null ? name.hashCode() : 0);
225 return result;
226 }
227
228 }