/* * Copyright 2009 NCHOVY * * Licensed 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.krakenapps.servlet.json.impl; import java.lang.reflect.Method; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; import javax.servlet.ServletException; import org.apache.felix.ipojo.annotations.Component; import org.apache.felix.ipojo.annotations.Invalidate; import org.apache.felix.ipojo.annotations.Provides; import org.apache.felix.ipojo.annotations.Requires; import org.apache.felix.ipojo.annotations.Validate; import org.krakenapps.http.HttpServiceManager; import org.krakenapps.http.KrakenHttpService; import org.krakenapps.servlet.json.JsonHttpMapping; import org.krakenapps.servlet.json.JsonHttpMethod; import org.krakenapps.servlet.json.JsonHttpServiceApi; import org.krakenapps.servlet.json.JsonHttpServlet; import org.krakenapps.servlet.json.JsonHttpService; import org.osgi.framework.BundleContext; import org.osgi.framework.InvalidSyntaxException; import org.osgi.framework.ServiceReference; import org.osgi.service.http.NamespaceException; import org.osgi.util.tracker.ServiceTracker; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @Component(name = "json-http-service-api") @Provides(specifications = { JsonHttpServiceApi.class }) public class JsonHttpServiceApiImpl extends ServiceTracker implements JsonHttpServiceApi { final Logger logger = LoggerFactory.getLogger(JsonHttpServiceApiImpl.class.getName()); private BundleContext bc; @Requires private HttpServiceManager httpServiceManager; private ConcurrentMap<String, JsonHttpService> serviceMap; /* * key: filter id, value: JsonMethod list */ private Map<String, List<String>> methodMap; public JsonHttpServiceApiImpl(BundleContext bc) { super(bc, JsonHttpService.class.getName(), null); this.bc = bc; } @Validate @SuppressWarnings("unused") private void start() { serviceMap = new ConcurrentHashMap<String, JsonHttpService>(); methodMap = new ConcurrentHashMap<String, List<String>>(); try { ServiceReference[] refs = bc.getServiceReferences(JsonHttpService.class.getName(), null); if (refs != null) { for (ServiceReference ref : refs) { JsonHttpService service = (JsonHttpService) bc.getService(ref); if (service == null) continue; addJsonMapping(service); } } } catch (InvalidSyntaxException e) { } open(); } @SuppressWarnings("unused") @Invalidate private void stop() { close(); serviceMap = null; methodMap = null; } private void addJsonMapping(JsonHttpService service) { List<String> jsonMethods = new ArrayList<String>(); Method[] methods = service.getClass().getMethods(); for (Method method : methods) { JsonHttpMethod m = method.getAnnotation(JsonHttpMethod.class); if (m != null) jsonMethods.add(method.getName()); } if (jsonMethods.size() > 0) { serviceMap.put(service.getName(), service); methodMap.put(service.getName(), jsonMethods); } } private void removeJsonMapping(JsonHttpService service) { serviceMap.remove(service.getName()); methodMap.remove(service.getName()); } @Override public void registerServlet(String serverId, String pathSpec) throws ServletException, NamespaceException { KrakenHttpService server = httpServiceManager.getHttpService(serverId); server.registerServlet(pathSpec, new JsonHttpServlet(this), null, null); } @Override public void unregisterServlet(String serverId) { } @Override public List<JsonHttpMapping> getFilterMappings(JsonHttpMapping criteria) { return null; } @Override public Object invokeJsonMethod(String filterId, String methodName, Map<String, Object> params) throws Exception { List<String> jsonMethods = methodMap.get(filterId); if (jsonMethods == null) { System.out.println("json method not found"); return null; } if (!jsonMethods.contains(methodName)) { System.out.println("json method name [" + methodName + "] not found"); return null; } JsonHttpService service = serviceMap.get(filterId); if (service == null) { System.out.println("json http service [" + filterId + "] not found"); return null; } logger.trace("calling json method: " + methodName); Method method = service.getClass().getMethod(methodName, new Class[] { Map.class }); return method.invoke(service, new Object[] { params }); } @Override public Object addingService(ServiceReference reference) { JsonHttpService service = (JsonHttpService) super.addingService(reference); logger.info("kraken json servlet: json webservice loaded: " + service.getName()); addJsonMapping(service); return service; } @Override public void removedService(ServiceReference reference, Object service) { JsonHttpService json = (JsonHttpService) service; logger.info("unloading json webservice: " + json.getName()); removeJsonMapping(json); super.removedService(reference, service); } @Override public Map<String, List<String>> getAvailableServices() { return new HashMap<String, List<String>>(methodMap); } }