Skip to content

Commit

Permalink
LPS-5137
Browse files Browse the repository at this point in the history
git-svn-id: svn://svn.liferay.com/repos/public/portal/trunk@38182 05bdf26c-840f-0410-9ced-eb539d925f36
  • Loading branch information
brianchandotcom committed Sep 24, 2009
1 parent c022140 commit c913b9f
Show file tree
Hide file tree
Showing 6 changed files with 199 additions and 6 deletions.
11 changes: 9 additions & 2 deletions definitions/liferay-hook_5_1_0.dtd
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@ This is the DTD for the Hook parameters for Liferay Portal.
"http://www.liferay.com/dtd/liferay-hook_5_1_0.dtd">
-->

<!ELEMENT hook (event*, model-listener*, portal-properties?, custom-jsp-dir?)>
<!ELEMENT hook (event*, model-listener*, portal-properties?, custom-jsp-dir?,
service*)>

<!ELEMENT event (event-class, event-type)>

Expand Down Expand Up @@ -71,4 +72,10 @@ theme.images.fast.load
-->
<!ELEMENT portal-properties (#PCDATA)>

<!ELEMENT custom-jsp-dir (#PCDATA)>
<!ELEMENT custom-jsp-dir (#PCDATA)>

<!ELEMENT service (service-type, service-impl)>

<!ELEMENT service-type (#PCDATA)>

<!ELEMENT service-impl (#PCDATA)>
11 changes: 9 additions & 2 deletions definitions/liferay-hook_5_2_0.dtd
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@ This is the DTD for the Hook parameters for Liferay Portal.
"http://www.liferay.com/dtd/liferay-hook_5_2_0.dtd">
-->

<!ELEMENT hook (portal-properties?, language-properties*, custom-jsp-dir?)>
<!ELEMENT hook (portal-properties?, language-properties*, custom-jsp-dir?,
service*)>

<!--
Not all portal properties can be overridden via a hook. The supported properties
Expand Down Expand Up @@ -61,4 +62,10 @@ theme.images.fast.load

<!ELEMENT language-properties (#PCDATA)>

<!ELEMENT custom-jsp-dir (#PCDATA)>
<!ELEMENT custom-jsp-dir (#PCDATA)>

<!ELEMENT service (service-type, service-impl)>

<!ELEMENT service-type (#PCDATA)>

<!ELEMENT service-impl (#PCDATA)>
11 changes: 9 additions & 2 deletions definitions/liferay-hook_5_3_0.dtd
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@ This is the DTD for the Hook parameters for Liferay Portal.
"http://www.liferay.com/dtd/liferay-hook_5_3_0.dtd">
-->

<!ELEMENT hook (portal-properties?, language-properties*, custom-jsp-dir?)>
<!ELEMENT hook (portal-properties?, language-properties*, custom-jsp-dir?,
service*)>

<!--
Not all portal properties can be overridden via a hook. The supported properties
Expand Down Expand Up @@ -61,4 +62,10 @@ theme.images.fast.load

<!ELEMENT language-properties (#PCDATA)>

<!ELEMENT custom-jsp-dir (#PCDATA)>
<!ELEMENT custom-jsp-dir (#PCDATA)>

<!ELEMENT service (service-type, service-impl)>

<!ELEMENT service-type (#PCDATA)>

<!ELEMENT service-impl (#PCDATA)>
6 changes: 6 additions & 0 deletions portal-impl/src/META-INF/base-spring.xml
Original file line number Diff line number Diff line change
Expand Up @@ -37,4 +37,10 @@
<property name="dataSource" ref="liferayDataSource" />
<property name="sessionFactory" ref="liferaySessionFactory" />
</bean>
<bean id="serviceHookAdvice" class="com.liferay.portal.spring.aop.ServiceHookAdvice" />
<aop:config>
<aop:aspect id="serviceHookAdvice.aspect" ref="serviceHookAdvice">
<aop:around pointcut="bean(*Service.impl)" method="invoke" />
</aop:aspect>
</aop:config>
</beans>
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@
import com.liferay.portal.service.persistence.BasePersistence;
import com.liferay.portal.servlet.filters.autologin.AutoLoginFilter;
import com.liferay.portal.servlet.filters.cache.CacheUtil;
import com.liferay.portal.spring.aop.ServiceHookAdvice;
import com.liferay.portal.struts.MultiMessageResources;
import com.liferay.portal.struts.MultiMessageResourcesFactory;
import com.liferay.portal.util.PortalInstances;
Expand All @@ -71,6 +72,7 @@
import java.io.File;
import java.io.InputStream;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Proxy;

Expand Down Expand Up @@ -340,6 +342,33 @@ protected void doInvokeDeploy(HotDeployEvent event) throws Exception {
}
}

ServicesContainer servicesContainer = new ServicesContainer();

_servicesContainerMap.put(servletContextName, servicesContainer);

List<Element> serviceEls = root.elements("service");

for (Element serviceEl : serviceEls) {
String serviceType = serviceEl.elementText("service-type");
String serviceImpl = serviceEl.elementText("service-impl");

Class serviceTypeClass = portletClassLoader.loadClass(serviceType);
Class serviceImplClass = portletClassLoader.loadClass(serviceImpl);

Constructor<?> serviceImplConstructor =
serviceImplClass.getConstructor(new Class[] {serviceTypeClass});

Object serviceImplInstance = serviceImplConstructor.newInstance(
PortalBeanLocatorUtil.locate(serviceType + ".impl"));

serviceImplInstance = Proxy.newProxyInstance(
portletClassLoader, new Class[] {serviceTypeClass},
new ContextClassLoaderBeanHandler(
serviceImplInstance, portletClassLoader));

servicesContainer.addService(serviceType, serviceImplInstance);
}

// Begin backwards compatibility for 5.1.0

ModelListenersContainer modelListenersContainer =
Expand Down Expand Up @@ -491,6 +520,13 @@ protected void doInvokeUndeploy(HotDeployEvent event) throws Exception {
destroyPortalProperties(portalProperties);
}

ServicesContainer servicesContainer = _servicesContainerMap.remove(
servletContextName);

if (servicesContainer != null) {
servicesContainer.unregisterServices();
}

unregisterClpMessageListeners(servletContext);

if (_log.isInfoEnabled()) {
Expand Down Expand Up @@ -1162,6 +1198,8 @@ protected void resetPortalProperties(Properties portalProperties)
new HashMap<String, ModelListenersContainer>();
private Map<String, Properties> _portalPropertiesMap =
new HashMap<String, Properties>();
private Map<String, ServicesContainer> _servicesContainerMap =
new HashMap<String, ServicesContainer>();
private Set<String> _servletContextNames = new HashSet<String>();

private class AuthenticatorsContainer {
Expand Down Expand Up @@ -1371,4 +1409,22 @@ public void unregisterModelListeners() {

}

private class ServicesContainer {

public void addService(String serviceType, Object serviceImplInstance) {
ServiceHookAdvice.setService(serviceType, serviceImplInstance);

_serviceTypes.add(serviceType);
}

public void unregisterServices() {
for (String serviceType : _serviceTypes) {
ServiceHookAdvice.setService(serviceType, null);
}
}

private List<String> _serviceTypes = new ArrayList<String>();

}

}
110 changes: 110 additions & 0 deletions portal-impl/src/com/liferay/portal/spring/aop/ServiceHookAdvice.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
/**
* Copyright (c) 2000-2009 Liferay, Inc. All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/

package com.liferay.portal.spring.aop;

import com.liferay.portal.kernel.log.Log;
import com.liferay.portal.kernel.log.LogFactoryUtil;
import com.liferay.portal.kernel.util.InitialThreadLocal;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.reflect.MethodSignature;

/**
* <a href="ServiceHookAdvice.java.html"><b><i>View Source</i></b></a>
*
* @author Brian Wing Shun Chan
*/
public class ServiceHookAdvice {

public static Object getService(String className) {
return _services.get(className);
}

public static void setService(String className, Object service) {
if (_log.isDebugEnabled()) {
if (service == null) {
_log.debug("Remove service hook " + className);
}
else {
_log.debug(
"Add service hook " + className + " " +
service.getClass().getName());
}
}

_services.put(className, service);
}

public Object invoke(ProceedingJoinPoint proceedingJoinPoint)
throws Throwable {

if (_immediatelyProceed.get()) {

// If the thread local variable to immedately proceed is set to
// true, then immediately proceed to prevent an infinite loop

_immediatelyProceed.set(Boolean.FALSE);

return proceedingJoinPoint.proceed();
}

MethodSignature methodSignature =
(MethodSignature)proceedingJoinPoint.getSignature();

String className = methodSignature.getDeclaringTypeName();

Object service = _services.get(className);

if (service == null) {
return proceedingJoinPoint.proceed();
}

_immediatelyProceed.set(Boolean.TRUE);

try {
Method method = methodSignature.getMethod();

return method.invoke(service, proceedingJoinPoint.getArgs());
}
catch (InvocationTargetException ite) {
throw ite.getTargetException();
}
finally {
_immediatelyProceed.remove();
}
}

private static Log _log = LogFactoryUtil.getLog(ServiceHookAdvice.class);

private static ThreadLocal<Boolean> _immediatelyProceed =
new InitialThreadLocal<Boolean>(Boolean.FALSE);
private static Map<String, Object> _services =
new ConcurrentHashMap<String, Object>();

}

0 comments on commit c913b9f

Please sign in to comment.