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.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          // Artifact
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         // name map
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         // uri
142         //
143         this.uri = createURI(artifact, name);
144 
145         //
146         // object name
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     // why not use String.split? Because String.split works using regular expressions
173     // and this should be way faster, but write a benchmark it out if you have time.
174     // Also this code is way simpler.
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 }