SchemaResponseMessageHandler.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.handler.impl;
022 
023 import java.util.ArrayList;
024 import java.util.List;
025 import java.util.Map;
026 
027 import org.apache.qpid.management.Messages;
028 import org.apache.qpid.management.Names;
029 import org.apache.qpid.management.Protocol;
030 import org.apache.qpid.management.domain.handler.base.BaseMessageHandler;
031 import org.apache.qpid.management.domain.model.type.Binary;
032 import org.apache.qpid.transport.codec.Decoder;
033 
034 /**
035  * Schema Response message handler.
036  * This handler is responsible to process 'S'(opcode) messages sent by the management broker containing the full
037  * schema details for a class.
038  
039  @author Andrea Gazzarini
040  */
041 public class SchemaResponseMessageHandler extends BaseMessageHandler
042 {  
043   /**
044    * Behavioural interface for classes that are responsible to deal with schema messages.
045    
046    @author Andrea Gazzarini
047    */
048   interface IProcessor 
049   {
050     /**
051      * Processes the incoming message using the given decoder.
052      
053      @param decoder the decoder used for dealing with incoming message.
054      */
055     void process(Decoder decoder);
056   }
057   
058   /**
059    * Processor responsible to deal with class schema related messages.
060    */
061   final IProcessor _classSchemaProcessor = new IProcessor()
062   {
063     public void process(Decoder decoder
064     {
065           try 
066           {            
067               String packageName = decoder.readStr8();
068               String className = decoder.readStr8();
069               
070               Binary schemaHash = new Binary(decoder.readBin128());
071               
072               int howManyProperties = decoder.readUint16();
073               int howManyStatistics = decoder.readUint16();
074               int howManyMethods = decoder.readUint16();
075 
076               _domainModel.addSchema(
077                       packageName, 
078                       className, 
079                       schemaHash,
080                       getAttributes(decoder, howManyProperties)
081                       getAttributes(decoder, howManyStatistics)
082                       getMethods(decoder, howManyMethods));
083           catch(Exception exception
084           {
085               _logger.error(exception,Messages.QMAN_100005_CLASS_SCHEMA_PROCESSING_FAILURE);
086           }
087     }
088   };
089   
090   /**
091    * Processor responsible to deal with class event related messages.
092    */
093   final IProcessor _eventSchemaProcessor = new IProcessor()
094   {
095     public void process(Decoder decoder
096     {
097           try 
098           {          
099               String packageName = decoder.readStr8();
100               String className = decoder.readStr8();
101               Binary hash = new Binary(decoder.readBin128());
102               int howManyArguments = decoder.readUint16();
103               
104               _domainModel.addEventSchema(
105                   packageName, 
106                   className, 
107                   hash, 
108                   getAttributes(decoder, howManyArguments));
109           catch(Exception exception
110           {
111               _logger.error(exception,Messages.QMAN_100006_EVENT_SCHEMA_PROCESSING_FAILURE);
112           }
113     }
114   };  
115   
116     /**
117      * Processes an incoming  schema response.
118      * This will be used for building the corresponding class definition.
119      
120      *  @param decoder the decoder used for parsing the incoming stream.
121      *  @param sequenceNumber the sequence number of the incoming message.
122      */
123     public void process (Decoder decoder, int sequenceNumber)
124     {        
125         try 
126         {
127           int classKind = decoder.readUint8();
128           switch(classKind)
129           {
130             case Protocol.CLASS :
131             {
132               _classSchemaProcessor.process(decoder);
133               break;
134             }
135             case Protocol.EVENT : 
136             {
137               _eventSchemaProcessor.process(decoder);   
138               break;
139             }
140             default 
141             {
142               _logger.error(Messages.QMAN_100011_UNKNOWN_CLASS_KIND,classKind);
143             }
144           }
145         catch(Exception exception
146         {
147             _logger.error(exception,Messages.QMAN_100012_SCHEMA_MESSAGE_PROCESSING_FAILURE);
148         }          
149     }
150     
151     /**
152      * Reads from the incoming message stream the properties definitions.
153      
154      @param decoder the decoder used for decode incoming data.
155      @param howManyProperties the number of properties to read. 
156      @return a list of maps. Each map contains a property definition.
157      */
158     List<Map<String, Object>> getAttributes(Decoder decoder,int howMany
159     {
160         List<Map<String, Object>> result = new ArrayList<Map<String, Object>>(howMany);        
161         for (int i = 0; i < howMany; i++ )
162         {
163             result.add(decoder.readMap());
164         }
165         return result;
166     }
167     
168     /**
169      * Reads the methods definitions from the incoming message stream.
170      
171      @param decoder the decoder used for decode incoming data.
172      @param howManyMethods the number of methods to read. 
173      @return a list method definitions.
174      */
175     List<MethodOrEventDataTransferObject> getMethods(Decoder decoder, int howManyMethods)
176     {
177         List<MethodOrEventDataTransferObject> result = new ArrayList<MethodOrEventDataTransferObject>(howManyMethods);
178         for (int i  = 0; i < howManyMethods; i++
179         {   
180             Map<String,Object> method = decoder.readMap();
181             int howManyArguments = (Integermethod.get(Names.ARG_COUNT_PARAM_NAME);
182 
183             List<Map<String,Object>> arguments = new ArrayList<Map<String,Object>>(howManyArguments);
184             for (int argIndex = 0; argIndex < howManyArguments; argIndex++)
185             {
186                 arguments.add(decoder.readMap());
187             }
188             result.add(new MethodOrEventDataTransferObject(method,arguments));
189         }        
190         return result;
191     }
192     
193     /**
194      * Reads the events definitions from the incoming message stream.
195      
196      @param decoder the decoder used for decode incoming data.
197      @param howManyEvents the number of events to read. 
198      @return a list event definitions.
199      */
200     List<MethodOrEventDataTransferObject> getEvents(Decoder decoder, int howManyEvents)
201     {
202         List<MethodOrEventDataTransferObject> result = new ArrayList<MethodOrEventDataTransferObject>(howManyEvents);
203         for (int i  = 0; i < howManyEvents; i++
204         {   
205             Map<String,Object> method = decoder.readMap();
206             int howManyArguments = (Integermethod.get(Names.ARG_COUNT_PARAM_NAME);
207 
208             List<Map<String,Object>> arguments = new ArrayList<Map<String,Object>>(howManyArguments);
209             for (int argIndex = 0; argIndex < howManyArguments; argIndex++)
210             {
211                 arguments.add(decoder.readMap());
212             }
213             result.add(new MethodOrEventDataTransferObject(method,arguments));
214         }        
215         return result;
216     }
217  }