/*
* Copyright (c) 2005-2010, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
*
* WSO2 Inc. licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except
* in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.synapse.config.xml.rest;
import org.apache.axiom.om.OMAttribute;
import org.apache.axiom.om.OMElement;
import org.apache.axis2.Constants;
import org.apache.axiom.om.OMNode;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.synapse.SynapseConstants;
import org.apache.synapse.SynapseException;
import org.apache.synapse.aspects.AspectConfiguration;
import org.apache.synapse.commons.util.PropertyHelper;
import org.apache.synapse.config.xml.XMLConfigConstants;
import org.apache.synapse.rest.API;
import org.apache.synapse.rest.Handler;
import org.apache.synapse.rest.RESTConstants;
import org.apache.synapse.rest.version.VersionStrategy;
import javax.xml.namespace.QName;
import java.util.Iterator;
import java.util.Properties;
public class APIFactory {
private static final Log log = LogFactory.getLog(APIFactory.class);
static final QName PROP_Q
= new QName(XMLConfigConstants.SYNAPSE_NAMESPACE, "property");
static final QName ATT_NAME = new QName("name");
static final QName ATT_VALUE = new QName("value");
public static API createAPI(OMElement apiElt) {
return createAPI(apiElt, new Properties());
}
public static API createAPI(OMElement apiElt, Properties properties) {
OMAttribute nameAtt = apiElt.getAttribute(new QName("name"));
if (nameAtt == null || "".equals(nameAtt.getAttributeValue())) {
handleException("Attribute 'name' is required for an API definition");
}
OMAttribute contextAtt = apiElt.getAttribute(new QName("context"));
if (contextAtt == null || "".equals(contextAtt.getAttributeValue())) {
handleException("Attribute 'context' is required for an API definition");
}
API api = new API(nameAtt.getAttributeValue(), contextAtt.getAttributeValue());
OMAttribute hostAtt = apiElt.getAttribute(new QName("hostname"));
if (hostAtt != null && !"".equals(hostAtt.getAttributeValue())) {
api.setHost(hostAtt.getAttributeValue());
}
VersionStrategy vStrategy = VersionStrategyFactory.createVersioningStrategy(api, apiElt);
api.setVersionStrategy(vStrategy);
OMAttribute portAtt = apiElt.getAttribute(new QName("port"));
if (portAtt != null && !"".equals(portAtt.getAttributeValue())) {
api.setPort(Integer.parseInt(portAtt.getAttributeValue()));
}
Iterator resources = apiElt.getChildrenWithName(new QName(
XMLConfigConstants.SYNAPSE_NAMESPACE, "resource"));
boolean noResources = true;
while (resources.hasNext()) {
OMElement resourceElt = (OMElement) resources.next();
api.addResource(ResourceFactory.createResource(resourceElt, properties));
noResources = false;
}
if (noResources) {
handleException("An API must contain at least one resource definition");
}
OMElement handlersElt = apiElt.getFirstChildWithName(new QName(
XMLConfigConstants.SYNAPSE_NAMESPACE, "handlers"));
if (handlersElt != null) {
Iterator handlers = handlersElt.getChildrenWithName(new QName(
XMLConfigConstants.SYNAPSE_NAMESPACE, "handler"));
while (handlers.hasNext()) {
OMElement handlerElt = (OMElement) handlers.next();
defineHandler(api, handlerElt);
}
}
OMAttribute trans = apiElt.getAttribute(
new QName(XMLConfigConstants.NULL_NAMESPACE, "transports"));
if (trans != null) {
String transports = trans.getAttributeValue();
if (!"".equals(transports)) {
if (Constants.TRANSPORT_HTTP.equals(transports)) {
api.setProtocol(RESTConstants.PROTOCOL_HTTP_ONLY);
} else if (Constants.TRANSPORT_HTTPS.equals(transports)) {
api.setProtocol(RESTConstants.PROTOCOL_HTTPS_ONLY);
} else {
handleException("Invalid protocol name: " + transports);
}
}
}
String nameString = api.getName();
if (nameString == null || "".equals(nameString)) {
nameString = SynapseConstants.ANONYMOUS_API;
}
AspectConfiguration aspectConfiguration = new AspectConfiguration(nameString);
api.configure(aspectConfiguration);
OMAttribute statistics = apiElt.getAttribute(
new QName(XMLConfigConstants.NULL_NAMESPACE, XMLConfigConstants.STATISTICS_ATTRIB_NAME));
if (statistics != null) {
String statisticsValue = statistics.getAttributeValue();
if (statisticsValue != null) {
if (XMLConfigConstants.STATISTICS_ENABLE.equals(statisticsValue)) {
aspectConfiguration.enableStatistics();
}
}
}
OMAttribute tracing = apiElt.getAttribute(
new QName(XMLConfigConstants.NULL_NAMESPACE, XMLConfigConstants.TRACE_ATTRIB_NAME));
if (tracing != null) {
String tracingValue = tracing.getAttributeValue();
if (tracingValue != null) {
if (XMLConfigConstants.TRACE_ENABLE.equals(tracingValue)) {
aspectConfiguration.enableTracing();
}
}
}
return api;
}
private static void defineHandler(API api, OMElement handlerElt) {
String handlerClass = handlerElt.getAttributeValue(new QName("class"));
if (handlerClass == null || "".equals(handlerClass)) {
handleException("A handler element must have a class attribute");
}
try {
Class clazz = APIFactory.class.getClassLoader().loadClass(handlerClass);
Handler handler = (Handler) clazz.newInstance();
api.addHandler(handler);
for (Iterator it = handlerElt.getChildrenWithName(PROP_Q); it.hasNext();) {
OMElement child = (OMElement) it.next();
String propName = child.getAttribute(ATT_NAME).getAttributeValue();
if (propName == null) {
handleException(
"A Class mediator property must specify the name attribute");
} else {
if (child.getAttribute(ATT_VALUE) != null) {
String value = child.getAttribute(ATT_VALUE).getAttributeValue();
handler.addProperty(propName, value);
PropertyHelper.setInstanceProperty(propName, value, handler);
} else {
OMNode omElt = child.getFirstElement();
if (omElt != null) {
handler.addProperty(propName, omElt);
PropertyHelper.setInstanceProperty(propName, omElt, handler);
} else {
handleException("A Class mediator property must specify " +
"name and value attributes, or a name and a child XML fragment");
}
}
}
}
} catch (Exception e) {
handleException("Error initializing API handler: " + handlerClass, e);
}
}
private static void handleException(String msg) {
log.error(msg);
throw new SynapseException(msg);
}
private static void handleException(String msg, Exception e) {
log.error(msg, e);
throw new SynapseException(msg, e);
}
}