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.HashSet;
024: import java.util.Iterator;
025: import java.util.List;
026: import java.util.Map;
027: import java.util.Set;
028: import java.util.TreeMap;
029: import java.util.TreeSet;
030:
031: import org.apache.geronimo.kernel.repository.Artifact;
032:
033: /**
034: * @version $Rev: 604483 $ $Date: 2007-12-15 10:28:19 -0800 (Sat, 15 Dec 2007) $
035: */
036: public class AbstractNameQuery implements Serializable {
037: private static final long serialVersionUID = 7444620122607155678L;
038:
039: private final Artifact artifact;
040: private final Map name;
041: private final Set interfaceTypes;
042:
043: private final URI uri;
044:
045: public AbstractNameQuery(AbstractName abstractName) {
046: this (abstractName, null);
047: }
048:
049: public AbstractNameQuery(AbstractName abstractName,
050: Set interfaceTypes) {
051: this .artifact = abstractName.getArtifact();
052: this .name = abstractName.getName();
053: this .interfaceTypes = interfaceTypes == null ? Collections.EMPTY_SET
054: : interfaceTypes;
055: this .uri = createURI(artifact, name, this .interfaceTypes);
056: }
057:
058: public AbstractNameQuery(Artifact artifact, Map name) {
059: this .artifact = artifact;
060: this .name = name;
061: this .interfaceTypes = Collections.EMPTY_SET;
062: this .uri = createURI(artifact, name, interfaceTypes);
063: }
064:
065: public AbstractNameQuery(Artifact artifact, Map name,
066: String interfaceType) {
067: this .artifact = artifact;
068: this .name = name;
069: if (interfaceType != null) {
070: this .interfaceTypes = Collections.singleton(interfaceType);
071: } else {
072: this .interfaceTypes = Collections.EMPTY_SET;
073: }
074: this .uri = createURI(artifact, name, interfaceTypes);
075: }
076:
077: public AbstractNameQuery(String interfaceType) {
078: this .artifact = null;
079: this .name = Collections.EMPTY_MAP;
080: this .interfaceTypes = Collections.singleton(interfaceType);
081: this .uri = createURI(artifact, name, interfaceTypes);
082: }
083:
084: public AbstractNameQuery(Artifact artifact, Map name,
085: Set interfaceTypes) {
086: this .artifact = artifact;
087: this .name = name;
088: if (interfaceTypes == null)
089: interfaceTypes = Collections.EMPTY_SET;
090: this .interfaceTypes = interfaceTypes;
091: this .uri = createURI(artifact, name, this .interfaceTypes);
092: }
093:
094: public AbstractNameQuery(URI uri) {
095: if (uri == null)
096: throw new NullPointerException("uri is null");
097:
098: //
099: // Artifact
100: //
101: String artifactString = uri.getPath();
102: //this doesn't seem to happen
103: // if (artifactString == null) throw new IllegalArgumentException("uri does not contain a path part used for the artifact");
104:
105: if (artifactString != null && artifactString.length() > 0) {
106: List artifactParts = split(artifactString, '/');
107: if (artifactParts.size() != 4) {
108: throw new IllegalArgumentException(
109: "uri path must be in the form [groupId]/[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: } else {
131: artifact = null;
132: }
133:
134: //
135: // name map
136: //
137: name = new TreeMap();
138: String nameString = uri.getQuery();
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 [vendorId]/artifactId/[version]/[type] : "
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: " + nameString);
160: // }
161:
162: String interfaceString = uri.getFragment();
163: List interfaces = split(interfaceString, ',');
164: interfaceTypes = new HashSet(interfaces);
165:
166: //
167: // uri
168: //
169: this .uri = createURI(artifact, name, interfaceTypes);
170: }
171:
172: private static List split(String source, char delim) {
173: List parts = new ArrayList();
174: if (source != null && source.length() > 0) {
175: for (int index = source.indexOf(delim); index >= 0; index = source
176: .indexOf(delim)) {
177: String part = source.substring(0, index);
178: source = source.substring(index + 1);
179: parts.add(part);
180: }
181: parts.add(source);
182: }
183: return parts;
184: }
185:
186: private static URI createURI(Artifact artifact, Map name,
187: Set interfaceTypes) {
188: StringBuffer queryString = new StringBuffer();
189: TreeMap treeMap = new TreeMap(name);
190: for (Iterator iterator = treeMap.entrySet().iterator(); iterator
191: .hasNext();) {
192: Map.Entry entry = (Map.Entry) iterator.next();
193: String key = (String) entry.getKey();
194: String value = (String) entry.getValue();
195: queryString.append(key).append('=').append(value);
196: if (iterator.hasNext()) {
197: queryString.append(',');
198: }
199: }
200: StringBuffer fragmentString = new StringBuffer();
201: TreeSet treeSet = new TreeSet(interfaceTypes);
202: for (Iterator iterator = treeSet.iterator(); iterator.hasNext();) {
203: String interfaceType = (String) iterator.next();
204: fragmentString.append(interfaceType);
205: if (iterator.hasNext()) {
206: fragmentString.append(',');
207: }
208: }
209: try {
210: return new URI(null, null, artifact == null ? null
211: : artifact.toString(), queryString.toString(),
212: fragmentString.toString());
213: } catch (URISyntaxException e) {
214: IllegalArgumentException illegalArgumentException = new IllegalArgumentException();
215: illegalArgumentException.initCause(e);
216: throw illegalArgumentException;
217: }
218: }
219:
220: public Artifact getArtifact() {
221: return artifact;
222: }
223:
224: public Map getName() {
225: return name;
226: }
227:
228: public Set getInterfaceTypes() {
229: return interfaceTypes;
230: }
231:
232: public String toString() {
233: return uri.toString();
234: }
235:
236: public URI toURI() {
237: return uri;
238: }
239:
240: public boolean equals(Object o) {
241: if (this == o)
242: return true;
243: if (o == null || getClass() != o.getClass())
244: return false;
245:
246: final AbstractNameQuery that = (AbstractNameQuery) o;
247:
248: if (artifact != null ? !artifact.equals(that.artifact)
249: : that.artifact != null)
250: return false;
251: if (interfaceTypes != null ? !interfaceTypes
252: .equals(that.interfaceTypes)
253: : that.interfaceTypes != null)
254: return false;
255: return !(name != null ? !name.equals(that.name)
256: : that.name != null);
257:
258: }
259:
260: public int hashCode() {
261: int result;
262: result = (artifact != null ? artifact.hashCode() : 0);
263: result = 29 * result + (name != null ? name.hashCode() : 0);
264: result = 29
265: * result
266: + (interfaceTypes != null ? interfaceTypes.hashCode()
267: : 0);
268: return result;
269: }
270:
271: public boolean matches(AbstractName info, Set targetInterfaceTypes) {
272: try {
273: if (!info.getName().entrySet().containsAll(name.entrySet())) {
274: return false;
275: }
276: if (!targetInterfaceTypes.containsAll(interfaceTypes)) {
277: return false;
278: }
279: if (artifact == null) {
280: return true;
281: }
282: Artifact otherArtifact = info.getArtifact();
283: return artifact.matches(otherArtifact);
284: } catch (NullPointerException e) {
285: e.printStackTrace();
286: return false;
287: }
288: }
289:
290: /**
291: * N.B. parameter info is supposed to be more specific than this.
292: * This is the opposite of the meaning of Artifact.matches.
293: *
294: * @param info
295: * @return if info is a more specific version of this name query.
296: */
297: public boolean matches(AbstractNameQuery info) {
298: if (!info.getName().entrySet().containsAll(name.entrySet())) {
299: return false;
300: }
301: if (!info.getInterfaceTypes().containsAll(interfaceTypes)) {
302: return false;
303: }
304: if (artifact == null) {
305: return true;
306: }
307: Artifact otherArtifact = info.getArtifact();
308: return artifact.matches(otherArtifact);
309: }
310: }
|