1 package org.exoplatform.services.portletcontainer.impl; 2 3 import java.util.HashMap ; 4 import java.util.Iterator ; 5 import java.util.List ; 6 import java.util.Map ; 7 8 import javax.portlet.PortletConfig; 9 import javax.portlet.PortletContext; 10 import javax.portlet.PortletException; 11 import javax.portlet.PreferencesValidator; 12 import javax.portlet.UnavailableException; 13 14 import org.apache.commons.logging.Log; 15 import org.exoplatform.Constants; 16 import org.exoplatform.container.PortalContainer; 17 import org.exoplatform.services.log.LogService; 18 import org.exoplatform.services.portletcontainer.impl.monitor.PortletMonitor; 19 import org.exoplatform.services.portletcontainer.impl.portletAPIImp.PortletConfigImp; 20 import org.exoplatform.services.portletcontainer.pci.model.*; 21 import org.picocontainer.MutablePicoContainer; 22 import org.picocontainer.Startable; 23 import org.picocontainer.defaults.DefaultPicoContainer; 24 25 29 30 37 public class PortletApplicationProxy implements Startable{ 38 private static final int WAITING_TIME_BEFORE_DESTROY = 50; PortletApplicationsHolder holder_; 40 private String portletAppName_; 41 private Map configs_; 42 private PortletMonitor monitor_; 43 private Log log_; 44 private MutablePicoContainer pico_; 45 46 public PortletApplicationProxy(PortletApplicationsHolder holder, 47 PortletMonitor monitor, 48 LogService logService) { 49 this.holder_ = holder; 50 this.monitor_ = monitor; 51 configs_ = new HashMap (); 52 this.log_ = logService.getLog("org.exoplatform.services.portletcontainer"); 53 pico_ = new DefaultPicoContainer(PortalContainer.getInstance()); 54 } 55 56 public javax.portlet.Portlet getPortlet(PortletContext portletContext, String portletName) 57 throws PortletException { 58 log_.debug("getPortlet() in PortletApplicationProxy entered"); 59 synchronized (monitor_) { 60 if (!monitor_.isInitialized(portletAppName_, portletName)) { 61 log_.debug("init monitor"); 62 init(monitor_, portletName, portletContext); 63 } 64 } 65 return (javax.portlet.Portlet) pico_. 66 getComponentInstance(portletAppName_ + Constants.PORTLET_ENCODER + portletName); 67 } 68 69 private void init(PortletMonitor monitor, String portletName, PortletContext portletContext) throws PortletException { 70 long accessTime = System.currentTimeMillis(); 71 if (!monitor.isInitialisationAllowed(portletAppName_, portletName, accessTime)) 72 throw new UnavailableException("Portlet initialization not possible"); 73 74 Portlet portletDatas = holder_.getPortletMetaData(portletAppName_, portletName); 75 PortletApp portletApp = holder_.getPortletApplication(portletAppName_); 76 PortletConfig config = new PortletConfigImp(portletDatas, portletContext, 77 portletApp.getSecurityConstraint(), 78 portletApp.getUserAttribute(), 79 portletApp.getCustomPortletMode(), 80 portletApp.getCustomWindowState()); 81 try { 82 if (pico_.getComponentInstance(portletAppName_ + Constants.PORTLET_ENCODER + 83 portletDatas.getPortletName()) == null){ 84 log_.debug("First registration of portlet : " + portletAppName_ + "/" + portletName); 85 registerPortlet(portletDatas.getPortletName()); 86 } 87 ((javax.portlet.Portlet) pico_.getComponentInstance(portletAppName_ + Constants.PORTLET_ENCODER 88 + portletDatas.getPortletName())).init(config); 89 configs_.put(portletDatas.getPortletName(), config); 90 String expirationStr = portletDatas.getExpirationCache() ; 91 int expiration = 0 ; 92 if(expirationStr != null) { 93 expiration = Integer.parseInt(portletDatas.getExpirationCache()) ; 94 } 95 monitor.init(portletAppName_, portletName, expiration); 96 monitor.setInitializationTime(portletAppName_, portletName, accessTime); 97 } catch (Throwable t) { 98 log_.error("exception while initializing portlet : " + portletName, t); 99 monitor.setLastInitFailureAccessTime(portletAppName_, portletName, accessTime); 100 releasePortlet(portletName); 101 if (t instanceof UnavailableException) { 102 UnavailableException e = (UnavailableException) t; 103 if (!e.isPermanent()) { 104 monitor.setUnavailabilityPeriod(portletAppName_, portletName, e.getUnavailableSeconds()); 105 } 106 throw e; 107 } 108 throw new PortletException("exception while initializing portlet", t); 109 } 110 } 111 112 public PortletConfig getPortletConfig(String portletName){ 113 return (PortletConfig) configs_.get(portletName); 114 } 115 116 private void registerPortlet(String key) { 117 try { 118 ClassLoader cl = Thread.currentThread().getContextClassLoader(); 119 pico_.registerComponentImplementation(portletAppName_ + Constants.PORTLET_ENCODER + key, 120 cl.loadClass(getPortletClassName(key))); 121 } catch (Exception e) { 122 log_.error("Can not register portlet : " + key, e); 123 } 124 } 125 126 private String getPortletClassName(String portletName) { 127 PortletApp portletApp = holder_.getPortletApplication(portletAppName_); 128 List portletMetaDataList = portletApp.getPortlet(); 129 for (Iterator iterator = portletMetaDataList.iterator(); iterator.hasNext();) { 130 Portlet portlet = (Portlet) iterator.next(); 131 if (portlet.getPortletName().equals(portletName)) 132 return portlet.getPortletClass(); 133 } 134 return null; 135 } 136 137 private void releasePortlet(String portletName) { 138 try { 139 pico_.unregisterComponent(portletAppName_ + Constants.PORTLET_ENCODER + portletName); 140 } catch (Exception e) { 141 log_.error("Can not release portlet : " + portletName, e); 142 } 143 } 144 145 public void destroy(String portletName) { 146 try { 147 boolean everLoaded = false; 148 synchronized (monitor_) { 149 everLoaded = monitor_.isInitialized(portletAppName_, portletName); 150 log_.debug("Was the portlet : " + portletAppName_ + "/" + portletName + " ever loaded : " + everLoaded); 151 monitor_.destroy(portletAppName_, portletName); 152 } 153 if (!everLoaded) 154 return; 155 if (pico_.getComponentInstance(portletAppName_ + Constants.PORTLET_ENCODER + portletName) == null){ 156 log_.debug("The portlet is already destroyed or in broken state"); 157 return; 158 } 159 log_.debug("Wait " + WAITING_TIME_BEFORE_DESTROY + " seconds before destroying the portlet"); 160 Thread.sleep(WAITING_TIME_BEFORE_DESTROY); 161 ((javax.portlet.Portlet) pico_. 162 getComponentInstance(portletAppName_ + Constants.PORTLET_ENCODER + portletName)).destroy(); 163 } catch (Throwable t) { 164 log_.error("If the portlet object throws a RuntimeException within the execution of the destroy " + 166 "method the portlet container must consider the portlet object successfully destroyed.", t); 167 } finally { 168 releasePortlet(portletName); 169 } 170 } 171 172 public void loadAndRegisterPortletClasses() { 173 String [] portletNames = getPortletNames(); 174 initMonitor(portletNames); 175 loadAndRegisterClassesByKey(portletNames); 176 } 177 178 private String [] getPortletNames() { 179 PortletApp portletApp = holder_.getPortletApplication(portletAppName_); 180 List portletMetaDataList = portletApp.getPortlet(); 181 String [] portletNames = new String [portletMetaDataList.size()]; 182 int i = 0; 183 for (Iterator iterator = portletMetaDataList.iterator(); iterator.hasNext();) { 184 Portlet portlet = (Portlet) iterator.next(); 185 portletNames[i] = portlet.getPortletName() ; 186 i++; 187 } 188 return portletNames; 189 } 190 191 protected void initMonitor(String [] portletNames) { 192 synchronized (monitor_) { 193 monitor_.registerPortletApp(portletAppName_); 194 } 195 for (int i = 0; i < portletNames.length; i++) { 196 String portletName = portletNames[i]; 197 registerPortletToMonitor(portletName); 198 } 199 } 200 201 public void registerPortletToMonitor(String portletName) { 202 synchronized (monitor_) { 203 monitor_.register(portletAppName_, portletName); 204 } 205 } 206 207 private void loadAndRegisterClassesByKey(String [] keys) { 208 for (int i = 0; i < keys.length; i++) { 209 String key = keys[i]; 210 registerPortlet(key); 211 } 212 } 213 214 public PreferencesValidator getValidator(String validatorClass) { 215 return (PreferencesValidator) pico_.getComponentInstance(portletAppName_ + 216 Constants.VALIDATOR_ENCODER + validatorClass); 217 } 218 219 public void loadAndRegisterValidatorClasses() { 220 String [] classNames = getValidatorClassNames(); 221 if (classNames == null) 222 return; 223 loadAndRegisterClasses(classNames); 224 } 225 226 public String [] getValidatorClassNames() { 227 PortletApp portletApp = holder_.getPortletApplication(portletAppName_); 228 List portletMetaDataList = portletApp.getPortlet(); 229 if (portletMetaDataList.size() == 0) 230 return null; 231 String [] validatorNames = new String [portletMetaDataList.size()]; 232 int i = 0; 233 for (Iterator iterator = portletMetaDataList.iterator(); iterator.hasNext();) { 234 Portlet portlet = (Portlet) iterator.next(); 235 236 ExoPortletPreferences preferences = portlet.getPortletPreferences(); 237 if (preferences != null) 238 validatorNames[i] = preferences.getPreferencesValidator(); 239 i++; 240 } 241 return validatorNames; 242 } 243 244 private void loadAndRegisterClasses(String [] classNames) { 245 for (int i = 0; i < classNames.length; i++) { 246 String className = classNames[i]; 247 if (className != null) { 248 try { 249 ClassLoader cl = Thread.currentThread().getContextClassLoader(); 250 pico_.registerComponentImplementation(portletAppName_ + Constants.VALIDATOR_ENCODER + className, 251 cl.loadClass(className)); 252 } catch (Exception e) { 253 log_.error("Can not load and register class : " + className, e); 254 } 255 } 256 } 257 } 258 259 public void load() { 260 loadAndRegisterPortletClasses(); 261 loadAndRegisterValidatorClasses(); 262 } 263 264 public void setApplicationName(String servletContextName) { 265 this.portletAppName_ = servletContextName; 266 } 267 268 public void start() { 269 } 270 271 public void stop() { 272 } 273 } | Popular Tags |