/******************************************************************************* * Copyright (c) 2007, 2014 compeople AG and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * compeople AG - initial API and implementation *******************************************************************************/ package org.eclipse.riena.internal.communication.publisher.hessian; import java.lang.reflect.Method; import java.net.Inet4Address; import java.net.UnknownHostException; import java.util.HashMap; import java.util.HashSet; import java.util.Set; import org.osgi.service.log.LogService; import org.eclipse.equinox.log.Logger; import org.eclipse.riena.communication.core.RemoteServiceDescription; import org.eclipse.riena.communication.core.hooks.IServiceMessageContext; import org.eclipse.riena.communication.core.hooks.IServiceMessageContextAccessor; import org.eclipse.riena.communication.core.publisher.IServicePublisher; import org.eclipse.riena.core.Log4r; /** * This is a Hessian based implementation of {@link IServicePublisher}. it * publish or unpublish OSGi Services as service end points for Hessian * protocol. * <p> * HessianRemoteServicePublisher becomes registered as OSGi Service with name * {@link IServicePublisher#ID}. The OSGi Service set the property * "riena.protocol=hessian". */ public class HessianRemoteServicePublisher implements IServicePublisher { private final static String PROTOCOL = "hessian"; //$NON-NLS-1$ private final static String SERVLET_PATH = "/hessian"; //$NON-NLS-1$ private final IServiceMessageContextAccessor mca = new MsgCxtAcc(); private final HashMap<String, RemoteServiceDescription> webServiceDescriptions; private final static Logger LOGGER = Log4r.getLogger(Activator.getDefault(), HessianRemoteServicePublisher.class); private final static String PORT = System.getProperty("org.eclipse.equinox.http.jetty.http.port"); // get the jetty PORT //$NON-NLS-1$ public HessianRemoteServicePublisher() { webServiceDescriptions = new HashMap<String, RemoteServiceDescription>(); } /* * (non-Javadoc) * * @seexeval.rcplabs.hessianx.server.IWebServicePublisher#publishService( * RemoteServiceDescription rsd ) */ public synchronized String publishService(final RemoteServiceDescription rsd) { if (!testInterface(rsd.getServiceInterfaceClass())) { final String error = "cannot publish " //$NON-NLS-1$ + rsd + " because its interface contains multiple methods with the same name." //$NON-NLS-1$ + "That is not allowed for remote services (even if they have a different signature)."; //$NON-NLS-1$ throw new RuntimeException(error); } String localhost = "localhost"; //$NON-NLS-1$ try { localhost = Inet4Address.getLocalHost().getHostAddress(); } catch (final UnknownHostException e) { // TODO: ok?? } if (PORT != null) { localhost = localhost + ":" + PORT; //$NON-NLS-1$ } final String url = "http://" + localhost + SERVLET_PATH + rsd.getPath(); //$NON-NLS-1$ rsd.setURL(url); webServiceDescriptions.put(SERVLET_PATH + rsd.getPath(), rsd); LOGGER.log(LogService.LOG_DEBUG, "published web service. " + rsd); //$NON-NLS-1$ LOGGER.log(LogService.LOG_DEBUG, "web service count: " + webServiceDescriptions.size()); //$NON-NLS-1$ return url; } private boolean testInterface(final Class<?> interfaceClazz) { final Set<String> methods = new HashSet<String>(); final Method[] declaredMethods = interfaceClazz.getDeclaredMethods(); for (final Method method : declaredMethods) { if (methods.contains(method.getName())) { return false; } methods.add(method.getName()); } return true; } /* * (non-Javadoc) * * @see * xeval.rcplabs.hessianx.server.IWebServicePublisher#unpublishService(java * .lang.String) */ public synchronized void unpublishService(final RemoteServiceDescription rsd) { webServiceDescriptions.remove(SERVLET_PATH + rsd.getPath()); LOGGER.log(LogService.LOG_DEBUG, "unpublished web service. " + rsd); //$NON-NLS-1$ LOGGER.log(LogService.LOG_DEBUG, "web service count: " + webServiceDescriptions.size()); //$NON-NLS-1$ } /* * (non-Javadoc) * * @see * org.eclipse.riena.communication.core.IRemoteServiceProtocol#getProtocol() */ public String getProtocol() { return PROTOCOL; } public synchronized RemoteServiceDescription findService(final String requestURI) { final RemoteServiceDescription rsd = webServiceDescriptions.get(requestURI); return rsd; } public IServiceMessageContextAccessor getMessageContextAccessor() { return mca; } static class MsgCxtAcc implements IServiceMessageContextAccessor { MsgCxtAcc() { super(); } public IServiceMessageContext getMessageContext() { return MessageContextHolder.getMessageContext(); } } }