001    /**
002     * Copyright (c) 2000-2012 Liferay, Inc. All rights reserved.
003     *
004     * The contents of this file are subject to the terms of the Liferay Enterprise
005     * Subscription License ("License"). You may not use this file except in
006     * compliance with the License. You can obtain a copy of the License by
007     * contacting Liferay, Inc. See the License for the specific language governing
008     * permissions and limitations under the License, including but not limited to
009     * distribution rights of the Software.
010     *
011     *
012     *
013     */
014    
015    package com.liferay.portal.server.capabilities;
016    
017    import java.lang.reflect.Field;
018    
019    import java.util.List;
020    
021    import javax.servlet.ServletContext;
022    
023    /**
024     * @author Brian Wing Shun Chan
025     * @author Igor Spasic
026     */
027    public class JettyServerCapabilities implements ServerCapabilities {
028    
029            public void determine(ServletContext servletContext) throws Exception {
030                    determineSupportsHotDeploy(servletContext);
031            }
032    
033            public boolean isSupportsHotDeploy() {
034                    return _supportsHotDeploy;
035            }
036    
037            protected void determineSupportsHotDeploy(ServletContext servletContext)
038                    throws Exception {
039    
040                    // org.eclipse.jetty.webapp.WebAppContext
041    
042                    Class<?> servletContextClass = servletContext.getClass();
043    
044                    Field outerClassField = servletContextClass.getDeclaredField("this$0");
045    
046                    outerClassField.setAccessible(true);
047    
048                    Object webAppContext = outerClassField.get(servletContext);
049    
050                    // org.eclipse.jetty.server.handler.AbstractHandler
051    
052                    Class<?> abstractHandlerClass = webAppContext.getClass();
053    
054                    for (int i = 0; i < 6; i++) {
055                            abstractHandlerClass = abstractHandlerClass.getSuperclass();
056                    }
057    
058                    // org.eclipse.jetty.server.Server
059    
060                    Field serverField = abstractHandlerClass.getDeclaredField("_server");
061    
062                    serverField.setAccessible(true);
063    
064                    Object server = serverField.get(webAppContext);
065    
066                    // org.eclipse.jetty.util.component.AggregateLifeCycle
067    
068                    Class<?> aggregateLifeCycleClass = server.getClass();
069    
070                    for (int i = 0; i < 4; i++) {
071                            aggregateLifeCycleClass = aggregateLifeCycleClass.getSuperclass();
072                    }
073    
074                    // org.eclipse.jetty.deploy.DeploymentManager
075    
076                    Field beansField = aggregateLifeCycleClass.getDeclaredField("_beans");
077    
078                    beansField.setAccessible(true);
079    
080                    Object deploymentManager = null;
081    
082                    List<?> aggregateLifeCycleBeans = (List<?>)beansField.get(server);
083    
084                    for (Object aggregateLifeCycleBean : aggregateLifeCycleBeans) {
085    
086                            // org.eclipse.jetty.util.component.AggregateLifeCycle$Bean
087    
088                            Class<?> aggregateLifeCycleBeanClass =
089                                    aggregateLifeCycleBean.getClass();
090    
091                            Field beanField = aggregateLifeCycleBeanClass.getDeclaredField(
092                                    "_bean");
093    
094                            beanField.setAccessible(true);
095    
096                            Object bean = beanField.get(aggregateLifeCycleBean);
097    
098                            Class<?> beanClass = bean.getClass();
099    
100                            String beanClassName = beanClass.getName();
101    
102                            if (beanClassName.equals(
103                                            "org.eclipse.jetty.deploy.DeploymentManager")) {
104    
105                                    deploymentManager = bean;
106    
107                                    break;
108                            }
109                    }
110    
111                    if (deploymentManager == null) {
112                            throw new Exception("DeploymentManager not found");
113                    }
114    
115                    // org.eclipse.jetty.deploy.providers.ScanningAppProvider
116    
117                    Class<?> deploymentManagerClass = deploymentManager.getClass();
118    
119                    Field providersField = deploymentManagerClass.getDeclaredField(
120                            "_providers");
121    
122                    providersField.setAccessible(true);
123    
124                    List<?> providers = (List<?>)providersField.get(deploymentManager);
125    
126                    boolean hotDeploySupported = false;
127    
128                    for (Object provider : providers) {
129                            Class<?> providerClass = provider.getClass();
130    
131                            String providerClassName = providerClass.getName();
132    
133                            if (!providerClassName.equals(
134                                            "org.eclipse.jetty.deploy.providers.ContextProvider")) {
135    
136                                    continue;
137                            }
138    
139                            Class<?> scanningAppProviderClass = providerClass.getSuperclass();
140    
141                            Field scanIntervalField = scanningAppProviderClass.getDeclaredField(
142                                    "_scanInterval");
143    
144                            scanIntervalField.setAccessible(true);
145    
146                            Integer scanInterval = (Integer)scanIntervalField.get(provider);
147    
148                            if ((scanInterval != null) && (scanInterval.intValue() > 0)) {
149                                    hotDeploySupported = true;
150    
151                                    break;
152                            }
153                    }
154    
155                    _supportsHotDeploy = hotDeploySupported;
156            }
157    
158            private boolean _supportsHotDeploy;
159    
160    }