{
boolean debug = log.isDebugEnabled();
String operationName = operationContext.getOperationName();
Annotation[][] parameterAnnotations = method.getParameterAnnotations();
Object[] params = new Object[parameterAnnotations.length];
OperationAttachment attachment = null;
for (int i = 0; i < parameterAnnotations.length; i++)
{
MappedPath pathTemplate;
MappedAttribute managedAttribute;
// Resolve path template and set as parameter to method
if ((pathTemplate = getAnnotation(parameterAnnotations[i], MappedPath.class)) != null)
{
params[i] = operationContext.getAddress().resolvePathTemplate(pathTemplate.value());
if (debug) log.debug("Resolved path template " + pathTemplate.value() + "=" + params[i]);
}
// Resolve attribute name and set as parameter to method
else if ((managedAttribute = getAnnotation(parameterAnnotations[i], MappedAttribute.class)) != null)
{
if (List.class == method.getParameterTypes()[i])
{
params[i] = operationContext.getAttributes().getValues(managedAttribute.value());
}
else if (String.class == method.getParameterTypes()[i])
{
params[i] = operationContext.getAttributes().getValue(managedAttribute.value());
}
else
{
throw new RuntimeException("The parameter type " + method.getParameterTypes()[i] +
" cannot be annotated by @" + MappedAttribute.class.getName() + ". Only List<String> and String are allowed.");
}
if (debug) log.debug("Resolved attribute " + managedAttribute.value() + "=" + params[i]);
}
// Method wants something from the OperationContext, or the entire OperationContext object.
else if ((getAnnotation(parameterAnnotations[i], ManagedContext.class)) != null)
{
Class<?> parameterType = method.getParameterTypes()[i];
if (RuntimeContext.class == parameterType)
{
params[i] = operationContext.getRuntimeContext();
}
else if (PathAddress.class == parameterType)
{
params[i] = operationContext.getAddress();
}
else if (OperationAttributes.class == parameterType)
{
params[i] = operationContext.getAttributes();
}
else if (ManagedUser.class == parameterType)
{
params[i] = operationContext.getUser();
}
else if (ModelValue.class.isAssignableFrom(parameterType))
{
if ( (attachment = operationContext.getAttachment(true)) != null)
{
try
{
// StringBuilder sb = new StringBuilder();
// InputStream in = attachment.getStream();
// byte[] buf = new byte[2048];
// while ( (in.read(buf)) != -1) {
// sb.append(new String(buf, Charset.forName("US-ASCII")));
// }
// String json = sb.toString();
// ByteArrayInputStream bais = new ByteArrayInputStream(json.getBytes());
// System.out.println("[\n"+json+"\n]");
params[i] = DmrModelValue.readFromJsonStream(attachment.getStream());
}
catch (IOException e)
{
log.error("IOException reading from JSON stream for detyped model.", e);
throw new OperationException(operationName, "Could not properly read data stream. See log for more details.", e);
}
}
else
{
throw new OperationException(operationName, "Data stream not available.");
}
}
else if (ModelProvider.class.isAssignableFrom(parameterType))
{
@SuppressWarnings("unchecked")
Class<? extends ModelValue> type = (Class<? extends ModelValue>) parameterType;
params[i] = operationContext.newModel(type);
}
else if (OperationContext.class == parameterType)
{
params[i] = operationContext;
}
}
else
{
Class<?> marshalClass = method.getParameterTypes()[i];
if (debug) log.debug("Encountered unannotated parameter. Will try and find marshaller for type " + marshalClass);
// Currently only one attachment is supported, and that's the data stream (input) of the management operation.
if (attachment != null)
{
throw new RuntimeException("Cannot unmarshal " + marshalClass + " for method " + methodName +
" and component " + managedClass.getName() + ". This is because input stream was already consumed. " +
"This can happen if the marshaled type is not declared before @ManagedContext for detyped ModelValue type.");
}
Marshaller<?> marshaller = operationContext.getBindingProvider().getMarshaller(marshalClass, operationContext.getContentType());
if (marshaller != null)
{
attachment = operationContext.getAttachment(true);
if (attachment == null) throw new OperationException(operationName, "No attachment was found for this operation.");
params[i] = marshaller.unmarshal(attachment.getStream());
if (debug) log.debug("Successfully unmarshaled object of type " + marshalClass);
}
else
{
throw new RuntimeException("Could not find marshaller for " + marshalClass +