1   /**
2    * Copyright (c) 2000-2008 Liferay, Inc. All rights reserved.
3    *
4    * Permission is hereby granted, free of charge, to any person obtaining a copy
5    * of this software and associated documentation files (the "Software"), to deal
6    * in the Software without restriction, including without limitation the rights
7    * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8    * copies of the Software, and to permit persons to whom the Software is
9    * furnished to do so, subject to the following conditions:
10   *
11   * The above copyright notice and this permission notice shall be included in
12   * all copies or substantial portions of the Software.
13   *
14   * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15   * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16   * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17   * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18   * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19   * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20   * SOFTWARE.
21   */
22  
23  package com.liferay.portal.events;
24  
25  import com.liferay.lock.service.LockServiceUtil;
26  import com.liferay.portal.kernel.bean.PortalBeanLocatorUtil;
27  import com.liferay.portal.kernel.cache.CacheRegistry;
28  import com.liferay.portal.kernel.cache.MultiVMPoolUtil;
29  import com.liferay.portal.kernel.events.ActionException;
30  import com.liferay.portal.kernel.events.SimpleAction;
31  import com.liferay.portal.kernel.messaging.MessageBus;
32  import com.liferay.portal.kernel.messaging.MessageBusUtil;
33  import com.liferay.portal.kernel.messaging.sender.MessageSender;
34  import com.liferay.portal.kernel.messaging.sender.SynchronousMessageSender;
35  import com.liferay.portal.kernel.scheduler.SchedulerEngineUtil;
36  import com.liferay.portal.kernel.search.SearchEngineUtil;
37  import com.liferay.portal.kernel.util.GetterUtil;
38  import com.liferay.portal.kernel.util.InstancePool;
39  import com.liferay.portal.kernel.util.ReleaseInfo;
40  import com.liferay.portal.model.CompanyConstants;
41  import com.liferay.portal.model.Release;
42  import com.liferay.portal.scheduler.SchedulerEngineProxy;
43  import com.liferay.portal.search.IndexSearcherImpl;
44  import com.liferay.portal.search.IndexWriterImpl;
45  import com.liferay.portal.search.lucene.LuceneSearchEngineUtil;
46  import com.liferay.portal.search.lucene.LuceneUtil;
47  import com.liferay.portal.service.ClassNameLocalServiceUtil;
48  import com.liferay.portal.service.ReleaseLocalServiceUtil;
49  import com.liferay.portal.tools.sql.DBUtil;
50  import com.liferay.portal.upgrade.UpgradeProcess;
51  import com.liferay.portal.util.PropsKeys;
52  import com.liferay.portal.util.PropsUtil;
53  import com.liferay.portal.velocity.LiferayResourceLoader;
54  import com.liferay.portal.verify.VerifyProcess;
55  
56  import org.apache.commons.collections.ExtendedProperties;
57  import org.apache.commons.logging.Log;
58  import org.apache.commons.logging.LogFactory;
59  import org.apache.velocity.app.Velocity;
60  import org.apache.velocity.runtime.RuntimeConstants;
61  
62  /**
63   * <a href="StartupAction.java.html"><b><i>View Source</i></b></a>
64   *
65   * @author Brian Wing Shun Chan
66   * @author Alexander Chow
67   *
68   */
69  public class StartupAction extends SimpleAction {
70  
71      public void run(String[] ids) throws ActionException {
72          try {
73              doRun(ids);
74          }
75          catch (RuntimeException re) {
76              throw re;
77          }
78          catch (Exception e) {
79              throw new ActionException(e);
80          }
81          finally {
82  
83              // Lucene
84  
85              LuceneUtil.checkLuceneDir(CompanyConstants.SYSTEM);
86          }
87      }
88  
89      protected void deleteTemporaryImages() throws Exception {
90          DBUtil dbUtil = DBUtil.getInstance();
91  
92          dbUtil.runSQL(_DELETE_TEMP_IMAGES_1);
93          dbUtil.runSQL(_DELETE_TEMP_IMAGES_2);
94      }
95  
96      protected void doRun(String[] ids) throws Exception {
97  
98          // Print release information
99  
100         System.out.println("Starting " + ReleaseInfo.getReleaseInfo());
101 
102         // Clear locks
103 
104         try {
105             LockServiceUtil.clear();
106         }
107         catch (Exception e) {
108             _log.error(e, e);
109         }
110 
111         // Add shutdown hook
112 
113         Runtime.getRuntime().addShutdownHook(new Thread(new ShutdownHook()));
114 
115         // Velocity
116 
117         LiferayResourceLoader.setListeners(PropsUtil.getArray(
118             PropsKeys.VELOCITY_ENGINE_RESOURCE_LISTENERS));
119 
120         ExtendedProperties props = new ExtendedProperties();
121 
122         props.setProperty(RuntimeConstants.RESOURCE_LOADER, "servlet");
123 
124         props.setProperty(
125             "servlet." + RuntimeConstants.RESOURCE_LOADER + ".class",
126             LiferayResourceLoader.class.getName());
127 
128         props.setProperty(
129             RuntimeConstants.RESOURCE_MANAGER_CLASS,
130             PropsUtil.get(PropsKeys.VELOCITY_ENGINE_RESOURCE_MANAGER));
131 
132         props.setProperty(
133             RuntimeConstants.RESOURCE_MANAGER_CACHE_CLASS,
134             PropsUtil.get(PropsKeys.VELOCITY_ENGINE_RESOURCE_MANAGER_CACHE));
135 
136         props.setProperty(
137             "velocimacro.library",
138             PropsUtil.get(PropsKeys.VELOCITY_ENGINE_VELOCIMACRO_LIBRARY));
139 
140         props.setProperty(
141             RuntimeConstants.RUNTIME_LOG_LOGSYSTEM_CLASS,
142             PropsUtil.get(PropsKeys.VELOCITY_ENGINE_LOGGER));
143 
144         props.setProperty(
145             "runtime.log.logsystem.log4j.category",
146             PropsUtil.get(PropsKeys.VELOCITY_ENGINE_LOGGER_CATEGORY));
147 
148         Velocity.setExtendedProperties(props);
149 
150         try {
151             Velocity.init();
152         }
153         catch (Exception e) {
154             _log.error(e, e);
155         }
156 
157         // Disable database caching before upgrade
158 
159         CacheRegistry.setActive(false);
160 
161         // Upgrade
162 
163         int buildNumber = ReleaseLocalServiceUtil.getBuildNumberOrCreate();
164 
165         if (buildNumber < ReleaseInfo.RELEASE_4_2_1_BUILD_NUMBER) {
166             String msg = "You must first upgrade to Liferay Portal 4.2.1";
167 
168             _log.fatal(msg);
169 
170             throw new RuntimeException(msg);
171         }
172 
173         boolean ranUpgradeProcess = false;
174 
175         String[] upgradeProcesses = PropsUtil.getArray(
176             PropsKeys.UPGRADE_PROCESSES);
177 
178         for (int i = 0; i < upgradeProcesses.length; i++) {
179             if (_log.isDebugEnabled()) {
180                 _log.debug("Initializing upgrade " + upgradeProcesses[i]);
181             }
182 
183             UpgradeProcess upgradeProcess = (UpgradeProcess)InstancePool.get(
184                 upgradeProcesses[i]);
185 
186             if (upgradeProcess == null) {
187                 _log.error(upgradeProcesses[i] + " cannot be found");
188 
189                 continue;
190             }
191 
192             if ((upgradeProcess.getThreshold() == 0) ||
193                 (upgradeProcess.getThreshold() > buildNumber)) {
194 
195                 if (_log.isInfoEnabled()) {
196                     _log.info("Running upgrade " + upgradeProcesses[i]);
197                 }
198 
199                 upgradeProcess.upgrade();
200 
201                 if (_log.isInfoEnabled()) {
202                     _log.info("Finished upgrade " + upgradeProcesses[i]);
203                 }
204 
205                 ranUpgradeProcess = true;
206             }
207             else {
208                 if (_log.isDebugEnabled()) {
209                     _log.debug(
210                         "Upgrade threshold " + upgradeProcess.getThreshold() +
211                             " will not trigger upgrade");
212 
213                     _log.debug("Skipping upgrade " + upgradeProcesses[i]);
214                 }
215             }
216         }
217 
218         // Class names
219 
220         ClassNameLocalServiceUtil.checkClassNames();
221 
222         // Delete temporary images
223 
224         deleteTemporaryImages();
225 
226         // Update indexes
227 
228         if (ranUpgradeProcess) {
229             DBUtil.getInstance().runSQLTemplate("indexes.sql", false);
230         }
231 
232         // Enable database caching after upgrade
233 
234         CacheRegistry.setActive(true);
235 
236         // Clear the caches only if the upgrade process was run
237 
238         if (ranUpgradeProcess) {
239             MultiVMPoolUtil.clear();
240         }
241 
242         // Messaging
243 
244         MessageBus messageBus = (MessageBus)PortalBeanLocatorUtil.locate(
245             MessageBus.class.getName());
246         MessageSender messageSender =
247             (MessageSender)PortalBeanLocatorUtil.locate(
248                 MessageSender.class.getName());
249         SynchronousMessageSender synchronousMessageSender =
250             (SynchronousMessageSender)PortalBeanLocatorUtil.locate(
251                 SynchronousMessageSender.class.getName());
252 
253         MessageBusUtil.init(
254             messageBus, messageSender, synchronousMessageSender);
255 
256         // Scheduler
257 
258         SchedulerEngineUtil.init(new SchedulerEngineProxy());
259 
260         SchedulerEngineUtil.start();
261 
262         // Search
263 
264         LuceneSearchEngineUtil.init();
265 
266         SearchEngineUtil.init(new IndexSearcherImpl(), new IndexWriterImpl());
267 
268         // Verify
269 
270         Release release = ReleaseLocalServiceUtil.getRelease();
271 
272         int verifyFrequency = GetterUtil.getInteger(
273             PropsUtil.get(PropsKeys.VERIFY_FREQUENCY));
274         boolean verified = release.isVerified();
275 
276         if ((verifyFrequency == VerifyProcess.ALWAYS) ||
277             ((verifyFrequency == VerifyProcess.ONCE) && !verified) ||
278             (ranUpgradeProcess)) {
279 
280             String[] verifyProcesses = PropsUtil.getArray(
281                 PropsKeys.VERIFY_PROCESSES);
282 
283             for (int i = 0; i < verifyProcesses.length; i++) {
284                 if (_log.isDebugEnabled()) {
285                     _log.debug(
286                         "Initializing verification " + verifyProcesses[i]);
287                 }
288 
289                 try {
290                     VerifyProcess verifyProcess = (VerifyProcess)Class.forName(
291                         verifyProcesses[i]).newInstance();
292 
293                     if (_log.isInfoEnabled()) {
294                         _log.info("Running verification " + verifyProcesses[i]);
295                     }
296 
297                     verifyProcess.verify();
298 
299                     if (_log.isInfoEnabled()) {
300                         _log.info(
301                             "Finished verification " + verifyProcesses[i]);
302                     }
303 
304                     verified = true;
305                 }
306                 catch (ClassNotFoundException cnfe) {
307                     _log.error(verifyProcesses[i] + " cannot be found");
308                 }
309                 catch (InstantiationException ie) {
310                     _log.error(verifyProcesses[i] + " cannot be initiated");
311                 }
312             }
313         }
314 
315         // Update release
316 
317         ReleaseLocalServiceUtil.updateRelease(verified);
318     }
319 
320     private static final String _DELETE_TEMP_IMAGES_1 =
321         "DELETE FROM Image WHERE imageId IN (SELECT articleImageId FROM " +
322             "JournalArticleImage WHERE tempImage = TRUE)";
323 
324     private static final String _DELETE_TEMP_IMAGES_2 =
325         "DELETE FROM JournalArticleImage where tempImage = TRUE";
326 
327     private static Log _log = LogFactory.getLog(StartupAction.class);
328 
329 }