View Javadoc

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.HashSet;
26  import java.util.Iterator;
27  import java.util.List;
28  import java.util.Map;
29  import java.util.Set;
30  import java.util.TreeMap;
31  import java.util.TreeSet;
32  
33  import org.apache.geronimo.kernel.repository.Artifact;
34  
35  /**
36   * @version $Rev: 430508 $ $Date: 2006-08-10 12:56:47 -0700 (Thu, 10 Aug 2006) $
37   */
38  public class AbstractNameQuery implements Serializable {
39      private static final long serialVersionUID = 7444620122607155678L;
40  
41      private final Artifact artifact;
42      private final Map name;
43      private final Set interfaceTypes;
44  
45      private final URI uri;
46  
47      public AbstractNameQuery(AbstractName abstractName) {
48          this(abstractName, null);
49      }
50  
51      public AbstractNameQuery(AbstractName abstractName, Set interfaceTypes) {
52          this.artifact = abstractName.getArtifact();
53          this.name = abstractName.getName();
54          this.interfaceTypes = interfaceTypes == null ? Collections.EMPTY_SET : interfaceTypes;
55          this.uri = createURI(artifact, name, this.interfaceTypes);
56      }
57  
58      public AbstractNameQuery(Artifact artifact, Map name) {
59          this.artifact = artifact;
60          this.name = name;
61          this.interfaceTypes = Collections.EMPTY_SET;
62          this.uri = createURI(artifact, name, interfaceTypes);
63      }
64  
65      public AbstractNameQuery(Artifact artifact, Map name, String interfaceType) {
66          this.artifact = artifact;
67          this.name = name;
68          if (interfaceType != null) {
69              this.interfaceTypes = Collections.singleton(interfaceType);
70          } else {
71              this.interfaceTypes = Collections.EMPTY_SET;
72          }
73          this.uri = createURI(artifact, name, interfaceTypes);
74      }
75  
76      public AbstractNameQuery(String interfaceType) {
77          this.artifact = null;
78          this.name = Collections.EMPTY_MAP;
79          this.interfaceTypes = Collections.singleton(interfaceType);
80          this.uri = createURI(artifact, name, interfaceTypes);
81      }
82  
83      public AbstractNameQuery(Artifact artifact, Map name, Set interfaceTypes) {
84          this.artifact = artifact;
85          this.name = name;
86          if (interfaceTypes == null) interfaceTypes = Collections.EMPTY_SET;
87          this.interfaceTypes = interfaceTypes;
88          this.uri = createURI(artifact, name, this.interfaceTypes);
89      }
90  
91      public AbstractNameQuery(URI uri) {
92          if (uri == null) throw new NullPointerException("uri is null");
93  
94          //
95          // Artifact
96          //
97          String artifactString = uri.getPath();
98          //this doesn't seem to happen
99  //        if (artifactString == null) throw new IllegalArgumentException("uri does not contain a path part used for the artifact");
100 
101         if (artifactString != null && artifactString.length() > 0) {
102             List artifactParts = split(artifactString, '/');
103             if (artifactParts.size() != 4) {
104                 throw new IllegalArgumentException("uri path must be in the form [groupId]/[artifactId]/[version]/[type] : " + artifactString);
105             }
106 
107             String groupId = (String) artifactParts.get(0);
108             if (groupId.length() == 0) groupId = null;
109 
110             String artifactId = (String) artifactParts.get(1);
111             if (artifactId.length() == 0) artifactId = null;
112 
113             String version = (String) artifactParts.get(2);
114             if (version.length() == 0) version = null;
115 
116             String type = (String) artifactParts.get(3);
117             if (type.length() == 0) type = null;
118 
119             artifact = new Artifact(groupId, artifactId, version, type);
120         } else {
121             artifact = null;
122         }
123 
124         //
125         // name map
126         //
127         name = new TreeMap();
128         String nameString = uri.getQuery();
129         List nameParts = split(nameString, ',');
130         for (Iterator iterator = nameParts.iterator(); iterator.hasNext();) {
131             String namePart = (String) iterator.next();
132             List keyValue = split(namePart, '=');
133             if (keyValue.size() != 2) {
134                 throw new IllegalArgumentException("uri query string must be in the form [vendorId]/artifactId/[version]/[type] : " + nameString);
135             }
136             String key = (String) keyValue.get(0);
137             String value = (String) keyValue.get(1);
138             if (name.containsKey(key)) {
139                 throw new IllegalArgumentException("uri query string contains the key '" + key + "' twice : " + nameString);
140             }
141             name.put(key, value);
142         }
143 //        if (name.isEmpty()) {
144 //            throw new IllegalArgumentException("name is empty: " + nameString);
145 //        }
146 
147         String interfaceString = uri.getFragment();
148         List interfaces = split(interfaceString, ',');
149         interfaceTypes = new HashSet(interfaces);
150 
151         //
152         // uri
153         //
154         this.uri = createURI(artifact, name, interfaceTypes);
155     }
156 
157     private static List split(String source, char delim) {
158         List parts = new ArrayList();
159         if (source != null && source.length() > 0) {
160             for (int index = source.indexOf(delim); index >= 0; index = source.indexOf(delim)) {
161                 String part = source.substring(0, index);
162                 source = source.substring(index + 1);
163                 parts.add(part);
164             }
165             parts.add(source);
166         }
167         return parts;
168     }
169 
170     private static URI createURI(Artifact artifact, Map name, Set interfaceTypes) {
171         StringBuffer queryString = new StringBuffer();
172         TreeMap treeMap = new TreeMap(name);
173         for (Iterator iterator = treeMap.entrySet().iterator(); iterator.hasNext();) {
174             Map.Entry entry = (Map.Entry) iterator.next();
175             String key = (String) entry.getKey();
176             String value = (String) entry.getValue();
177             queryString.append(key).append('=').append(value);
178             if (iterator.hasNext()) {
179                 queryString.append(',');
180             }
181         }
182         StringBuffer fragmentString = new StringBuffer();
183         TreeSet treeSet = new TreeSet(interfaceTypes);
184         for (Iterator iterator = treeSet.iterator(); iterator.hasNext();) {
185             String interfaceType = (String) iterator.next();
186             fragmentString.append(interfaceType);
187             if (iterator.hasNext()) {
188                 fragmentString.append(',');
189             }
190         }
191         try {
192             return new URI(null, null, artifact == null? null: artifact.toString(), queryString.toString(), fragmentString.toString());
193         } catch (URISyntaxException e) {
194             IllegalArgumentException illegalArgumentException = new IllegalArgumentException();
195             illegalArgumentException.initCause(e);
196             throw illegalArgumentException;
197         }
198     }
199 
200 
201     public Artifact getArtifact() {
202         return artifact;
203     }
204 
205     public Map getName() {
206         return name;
207     }
208 
209     public Set getInterfaceTypes() {
210         return interfaceTypes;
211     }
212 
213     public String toString() {
214         return uri.toString();
215     }
216 
217     public URI toURI() {
218         return uri;
219     }
220 
221     public boolean equals(Object o) {
222         if (this == o) return true;
223         if (o == null || getClass() != o.getClass()) return false;
224 
225         final AbstractNameQuery that = (AbstractNameQuery) o;
226 
227         if (artifact != null ? !artifact.equals(that.artifact) : that.artifact != null) return false;
228         if (interfaceTypes != null ? !interfaceTypes.equals(that.interfaceTypes) : that.interfaceTypes != null)
229             return false;
230         return !(name != null ? !name.equals(that.name) : that.name != null);
231 
232     }
233 
234     public int hashCode() {
235         int result;
236         result = (artifact != null ? artifact.hashCode() : 0);
237         result = 29 * result + (name != null ? name.hashCode() : 0);
238         result = 29 * result + (interfaceTypes != null ? interfaceTypes.hashCode() : 0);
239         return result;
240     }
241 
242 
243     public boolean matches(AbstractName info, Set targetInterfaceTypes) {
244         if (!info.getName().entrySet().containsAll(name.entrySet())) {
245             return false;
246         }
247         if (!targetInterfaceTypes.containsAll(interfaceTypes)) {
248             return false;
249         }
250         if (artifact == null) {
251             return true;
252         }
253         Artifact otherArtifact = info.getArtifact();
254         return artifact.matches(otherArtifact);
255     }
256 
257     /**
258      * N.B. parameter info is supposed to be more specific than this.
259      * This is the opposite of the meaning of Artifact.matches.
260      *
261      * @param info
262      * @return if info is a more specific version of this name query.
263      */
264     public boolean matches(AbstractNameQuery info) {
265         if (!info.getName().entrySet().containsAll(name.entrySet())) {
266             return false;
267         }
268         if (!info.getInterfaceTypes().containsAll(interfaceTypes)) {
269             return false;
270         }
271         if (artifact == null) {
272             return true;
273         }
274         Artifact otherArtifact = info.getArtifact();
275         return artifact.matches(otherArtifact);
276     }
277 }