QpidPackage.java
001 /*
002  *
003  * Licensed to the Apache Software Foundation (ASF) under one
004  * or more contributor license agreements.  See the NOTICE file
005  * distributed with this work for additional information
006  * regarding copyright ownership.  The ASF licenses this file
007  * to you under the Apache License, Version 2.0 (the
008  * "License"); you may not use this file except in compliance
009  * with the License.  You may obtain a copy of the License at
010  *
011  *   http://www.apache.org/licenses/LICENSE-2.0
012  *
013  * Unless required by applicable law or agreed to in writing,
014  * software distributed under the License is distributed on an
015  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
016  * KIND, either express or implied.  See the License for the
017  * specific language governing permissions and limitations
018  * under the License.
019  *
020  */
021 package org.apache.qpid.management.domain.model;
022 
023 import java.util.HashMap;
024 import java.util.List;
025 import java.util.Map;
026 import java.util.UUID;
027 
028 import org.apache.qpid.management.domain.handler.impl.IMethodInvocationListener;
029 import org.apache.qpid.management.domain.handler.impl.MethodOrEventDataTransferObject;
030 import org.apache.qpid.management.domain.model.type.Binary;
031 
032 /**
033  * Qpid package definition.
034  * A grouping of class definitions that are related to a single software component. 
035  * The package concept is used to extend the management schema beyond just the QPID software components.
036  * The name is prefixed with "Qpid" for avoiding name conficts with java.lang.Package.
037  
038  @author Andrea Gazzarini
039  */
040 final class QpidPackage
041 {  
042     /**
043      * Qpid class identity.
044      * Each qpid class is uniquely identifier by its name and schema-hash.
045      * The schema hash is an MD5 checksum of the schema for a class. 
046      * It is there so we can support the case where two different versions of the same class are present at the same time.
047      
048      @author Andrea Gazzarini
049      */
050     class QpidClassIdentity {
051         final String name;
052         final Binary hash;
053         
054         /**
055          * Builds a new class identity with the given name and hash.
056          
057          @param name the class name.
058          @param hash is an MD5 checksum of the schema of this outer class.
059          */
060         QpidClassIdentity(String name,Binary hash) {
061             this.name = name;
062             this.hash = hash;
063         }
064         
065         @Override
066         public int hashCode ()
067         {
068             return name.hashCode()+hash.hashCode();
069         }
070         
071         @Override
072         public boolean equals (Object obj)
073         {
074             QpidClassIdentity identity = (QpidClassIdentityobj;
075             return name.equals(identity.name&& hash.equals(identity.hash);
076         }
077     }
078     
079     private String _name;
080     private DomainModel _parent;
081     private Map<QpidClassIdentity, QpidClass> _classes = new HashMap<QpidClassIdentity, QpidClass>();
082     private Map<QpidClassIdentity, QpidEvent> _events = new HashMap<QpidClassIdentity, QpidEvent>();
083     
084     /**
085      * Builds a new package with the supplied name.
086      
087      @param name the name of the package.
088      */
089     QpidPackage(String name, DomainModel parent)
090     {
091         this._name = name;
092         this._parent = parent;
093     }
094 
095     /**
096      * Returns the identifier of the broker which contains this package.
097      @return
098      */
099     UUID getOwnerId() 
100     {
101         return _parent.getBrokerId();
102     }
103     
104     /**
105      * Returns the name of this package.
106      
107      @return the name of this package.
108      */
109     String getName ()
110     {
111         return _name;
112     }
113 
114     /**
115      * Adds a class definition to this package.
116      * The class will be added only if its definition doesn't already exists. 
117      
118      @param className the name of the class.
119      @param classHash the class schema hash.
120      @param properties the properties of the class.
121      @param statistics the statistics of the class.
122      @param methods the methods of the class.
123      @param events the events of the class.
124      
125      @throws UnableToBuildFeatureException when the class definition cannot be built due to a feature build failure.
126      */
127     void addClassDefinition (
128             String className, 
129             Binary classHash,
130             List<Map<String, Object>> properties,
131             List<Map<String, Object>> statistics,
132             List<MethodOrEventDataTransferObject> methodsthrows UnableToBuildFeatureException
133     {
134         getQpidClass(className,classHash,true).setSchema(properties,statistics,methods);
135     }
136 
137     void addEventDefinition (
138             String eventClassName, 
139             Binary classHash,
140             List<Map<String, Object>> argumentsthrows UnableToBuildFeatureException
141     {
142         getQpidEvent(eventClassName,classHash,true).setSchema(arguments);
143     }
144     
145     /**
146      * Returns true if this package contains the given class definition.
147      
148      @param className the name of the class.
149      @return true if this package contains the class definition, false otherwise.
150      */
151     boolean alreadyContainsClassDefinition (String className, Binary hash)
152     {
153         return _classes.containsKey(new QpidClassIdentity(className,hash));
154     }
155 
156     /**
157      * Injects into a class the given object instance instrumentation data.
158      
159      @param className the of the class the injected object data belongs to.
160      @param objectId the object identifier.
161      @param rawData the instrumentation data (in raw format).
162      */
163     void setObjectInstanceInstrumentationRawData (String className, Binary classHash,Binary objectId, byte[] rawData)
164     {
165         getQpidClass(className, classHash,true).addInstrumentationData(objectId,rawData);
166     }
167     
168     /**
169      * Injects into a class the given object instance configuration data.
170      
171      @param className the of the class the injected object data belongs to.
172      @param objectId the object identifier.
173      @param rawData the configuration data (in raw format).
174      */
175     void setObjectInstanceConfigurationRawData (String className,Binary classHash, Binary objectId, byte[] rawData)
176     {
177         getQpidClass(className,classHash,true).addConfigurationData(objectId,rawData);
178     }
179 
180     void setEventInstanceRawData (String eventName,Binary eventHash, byte[] rawData,long currentTimestamp,int severity)
181     {
182         getQpidEvent(eventName,eventHash,true).addEventData(rawData, currentTimestamp, severity);
183     }    
184     
185     /**
186      * Returns the definition of the class with given name.
187      
188      @param className the name of the class.
189      @param hash the class hash.
190      @param store a flag indicating if a just created class must be stored or not.
191      @return the definition of the class with given name.
192      */
193     QpidClass getQpidClass(String className, Binary hash, boolean store
194     {
195         QpidClassIdentity identity = new QpidClassIdentity(className,hash);
196         QpidClass classDefinition = _classes.get(identity);
197         if (classDefinition == null
198         {
199             classDefinition = new QpidClass(className, hash,this);
200             if (store
201             {
202             _classes.put(identity,classDefinition);
203             }
204          }
205         return classDefinition;
206     }
207     
208     /**
209      * Returns the definition of the class with given name.
210      
211      @param className the name of the class.
212      @param hash the class hash.
213      @param store a flag indicating if a just created class must be stored or not.
214      @return the definition of the class with given name.
215      */
216     QpidEvent getQpidEvent(String className, Binary hash, boolean store
217     {
218         QpidClassIdentity identity = new QpidClassIdentity(className,hash);
219         QpidEvent eventDefinition = _events.get(identity);
220         if (eventDefinition == null
221         {
222             eventDefinition = new QpidEvent(className, hash,this);
223             if (store
224             {
225             _events.put(identity,eventDefinition);
226             }
227          }
228         return eventDefinition;
229     }    
230     
231     /**
232      * Returns a string representation of this class.
233      * That is, this method returns the simple name (not FQN) of this class.
234      */
235     @Override
236     public String toString ()
237     {
238         return _name;
239     }
240 
241     /**
242      * Removes the object instance associated to the given parameters.
243      
244      @param className the class definition of the object instance.
245      @param classHash the class hash
246      @param objectId the object identifier.
247      */
248     void removeObjectInstance (String className, Binary classHash, Binary objectId)
249     {
250         QpidClass qpidClass = getQpidClass(className,classHash,false);
251         qpidClass.removeObjectInstance(objectId);
252     }
253 
254     /**
255      * Releases all previously acquired resources of this package.
256      */
257     void releaseResources ()
258     {
259         for (QpidClass qpidClass : _classes.values())
260         {
261             qpidClass.releaseResources();
262         }
263         
264         for (QpidEvent qpidEvent: _events.values())
265         {
266             qpidEvent.releaseResources();
267         }        
268     }
269 
270     /**
271      * Returns the method invocation listener of the corresponing parent domain model.
272      
273      @return the method invocation listener of the corresponing parent domain model.
274      */
275     IMethodInvocationListener getMethodInvocationListener ()
276     {
277         return _parent.getMethodInvocationListener();
278     }
279 }