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 = (Integer) method.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 = (Integer) method.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 }
|