1   /**
2    * Copyright (c) 2000-2009 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.PortalException;
27  import com.liferay.portal.SystemException;
28  import com.liferay.portal.kernel.bean.PortalBeanLocatorUtil;
29  import com.liferay.portal.kernel.cache.CacheRegistry;
30  import com.liferay.portal.kernel.cache.MultiVMPoolUtil;
31  import com.liferay.portal.kernel.events.ActionException;
32  import com.liferay.portal.kernel.events.SimpleAction;
33  import com.liferay.portal.kernel.log.Log;
34  import com.liferay.portal.kernel.log.LogFactoryUtil;
35  import com.liferay.portal.kernel.messaging.MessageBus;
36  import com.liferay.portal.kernel.messaging.MessageBusUtil;
37  import com.liferay.portal.kernel.messaging.sender.MessageSender;
38  import com.liferay.portal.kernel.messaging.sender.SynchronousMessageSender;
39  import com.liferay.portal.kernel.scheduler.SchedulerEngineUtil;
40  import com.liferay.portal.kernel.util.GetterUtil;
41  import com.liferay.portal.kernel.util.InstancePool;
42  import com.liferay.portal.kernel.util.ReleaseInfo;
43  import com.liferay.portal.kernel.velocity.VelocityEngineUtil;
44  import com.liferay.portal.model.CompanyConstants;
45  import com.liferay.portal.model.Release;
46  import com.liferay.portal.scheduler.SchedulerEngineProxy;
47  import com.liferay.portal.search.lucene.LuceneUtil;
48  import com.liferay.portal.service.ClassNameLocalServiceUtil;
49  import com.liferay.portal.service.ReleaseLocalServiceUtil;
50  import com.liferay.portal.tools.sql.DBUtil;
51  import com.liferay.portal.upgrade.UpgradeProcess;
52  import com.liferay.portal.util.PropsKeys;
53  import com.liferay.portal.util.PropsUtil;
54  import com.liferay.portal.util.PropsValues;
55  import com.liferay.portal.verify.VerifyProcess;
56  
57  import java.io.IOException;
58  
59  import java.sql.SQLException;
60  
61  import javax.naming.NamingException;
62  
63  /**
64   * <a href="StartupAction.java.html"><b><i>View Source</i></b></a>
65   *
66   * @author Brian Wing Shun Chan
67   * @author Alexander Chow
68   * @author Raymond Augé
69   *
70   */
71  public class StartupAction extends SimpleAction {
72  
73      public void run(String[] ids) throws ActionException {
74          try {
75              doRun(ids);
76          }
77          catch (RuntimeException re) {
78              throw re;
79          }
80          catch (Exception e) {
81              throw new ActionException(e);
82          }
83          finally {
84              LuceneUtil.checkLuceneDir(CompanyConstants.SYSTEM);
85          }
86      }
87  
88      protected void deleteTemporaryImages()
89          throws IOException, NamingException, SQLException {
90  
91          DBUtil dbUtil = DBUtil.getInstance();
92  
93          dbUtil.runSQL(_DELETE_TEMP_IMAGES_1);
94          dbUtil.runSQL(_DELETE_TEMP_IMAGES_2);
95      }
96  
97      protected void doRun(String[] ids) throws PortalException, SystemException {
98  
99          // Print release information
100 
101         System.out.println("Starting " + ReleaseInfo.getReleaseInfo());
102 
103         // Clear locks
104 
105         try {
106             LockServiceUtil.clear();
107         }
108         catch (Exception e) {
109             _log.error(e, e);
110         }
111 
112         // Add shutdown hook
113 
114         Runtime.getRuntime().addShutdownHook(new Thread(new ShutdownHook()));
115 
116         // Velocity
117 
118         VelocityEngineUtil.init();
119 
120         // Disable database caching before upgrade
121 
122         CacheRegistry.setActive(false);
123 
124         // Upgrade
125 
126         int buildNumber = ReleaseLocalServiceUtil.getBuildNumberOrCreate();
127 
128         if (buildNumber < ReleaseInfo.RELEASE_4_2_1_BUILD_NUMBER) {
129             String msg = "You must first upgrade to Liferay Portal 4.2.1";
130 
131             _log.fatal(msg);
132 
133             throw new RuntimeException(msg);
134         }
135 
136         boolean ranUpgradeProcess = false;
137 
138         String[] upgradeProcesses = PropsUtil.getArray(
139             PropsKeys.UPGRADE_PROCESSES);
140 
141         for (int i = 0; i < upgradeProcesses.length; i++) {
142             if (_log.isDebugEnabled()) {
143                 _log.debug("Initializing upgrade " + upgradeProcesses[i]);
144             }
145 
146             UpgradeProcess upgradeProcess = (UpgradeProcess)InstancePool.get(
147                 upgradeProcesses[i]);
148 
149             if (upgradeProcess == null) {
150                 _log.error(upgradeProcesses[i] + " cannot be found");
151 
152                 continue;
153             }
154 
155             if ((upgradeProcess.getThreshold() == 0) ||
156                 (upgradeProcess.getThreshold() > buildNumber)) {
157 
158                 if (_log.isInfoEnabled()) {
159                     _log.info("Running upgrade " + upgradeProcesses[i]);
160                 }
161 
162                 upgradeProcess.upgrade();
163 
164                 if (_log.isInfoEnabled()) {
165                     _log.info("Finished upgrade " + upgradeProcesses[i]);
166                 }
167 
168                 ranUpgradeProcess = true;
169             }
170             else {
171                 if (_log.isDebugEnabled()) {
172                     _log.debug(
173                         "Upgrade threshold " + upgradeProcess.getThreshold() +
174                             " will not trigger upgrade");
175 
176                     _log.debug("Skipping upgrade " + upgradeProcesses[i]);
177                 }
178             }
179         }
180 
181         // Class names
182 
183         ClassNameLocalServiceUtil.checkClassNames();
184 
185         // Delete temporary images
186 
187         try {
188             deleteTemporaryImages();
189         }
190         catch (Exception e) {
191             _log.error(e, e);
192         }
193 
194         // Update indexes
195 
196         if (ranUpgradeProcess) {
197             try {
198                 DBUtil.getInstance().runSQLTemplate("indexes.sql", false);
199             }
200             catch (Exception e) {
201                 _log.error(e, e);
202             }
203         }
204 
205         // Enable database caching after upgrade
206 
207         CacheRegistry.setActive(true);
208 
209         // Clear the caches only if the upgrade process was run
210 
211         if (ranUpgradeProcess) {
212             MultiVMPoolUtil.clear();
213         }
214 
215         // Messaging
216 
217         MessageBus messageBus = (MessageBus)PortalBeanLocatorUtil.locate(
218             MessageBus.class.getName());
219         MessageSender messageSender =
220             (MessageSender)PortalBeanLocatorUtil.locate(
221                 MessageSender.class.getName());
222         SynchronousMessageSender synchronousMessageSender =
223             (SynchronousMessageSender)PortalBeanLocatorUtil.locate(
224                 SynchronousMessageSender.class.getName());
225 
226         MessageBusUtil.init(
227             messageBus, messageSender, synchronousMessageSender);
228 
229         // Scheduler
230 
231         SchedulerEngineUtil.init(new SchedulerEngineProxy());
232 
233         SchedulerEngineUtil.start();
234 
235         // Verify
236 
237         Release release = ReleaseLocalServiceUtil.getRelease();
238 
239         // LPS-1880
240 
241         boolean tempIndexReadOnly = PropsValues.INDEX_READ_ONLY;
242 
243         PropsValues.INDEX_READ_ONLY = true;
244 
245         int verifyFrequency = GetterUtil.getInteger(
246             PropsUtil.get(PropsKeys.VERIFY_FREQUENCY));
247         boolean verified = release.isVerified();
248 
249         if ((verifyFrequency == VerifyProcess.ALWAYS) ||
250             ((verifyFrequency == VerifyProcess.ONCE) && !verified) ||
251             (ranUpgradeProcess)) {
252 
253             if (!ranUpgradeProcess) {
254                 PropsUtil.set(PropsKeys.INDEX_ON_STARTUP, "true");
255             }
256 
257             String[] verifyProcesses = PropsUtil.getArray(
258                 PropsKeys.VERIFY_PROCESSES);
259 
260             for (int i = 0; i < verifyProcesses.length; i++) {
261                 if (_log.isDebugEnabled()) {
262                     _log.debug(
263                         "Initializing verification " + verifyProcesses[i]);
264                 }
265 
266                 try {
267                     VerifyProcess verifyProcess = (VerifyProcess)Class.forName(
268                         verifyProcesses[i]).newInstance();
269 
270                     if (_log.isInfoEnabled()) {
271                         _log.info("Running verification " + verifyProcesses[i]);
272                     }
273 
274                     verifyProcess.verify();
275 
276                     if (_log.isInfoEnabled()) {
277                         _log.info(
278                             "Finished verification " + verifyProcesses[i]);
279                     }
280 
281                     verified = true;
282                 }
283                 catch (ClassNotFoundException cnfe) {
284                     _log.error(verifyProcesses[i] + " cannot be found");
285                 }
286                 catch (IllegalAccessException iae) {
287                     _log.error(verifyProcesses[i] + " cannot be accessed");
288                 }
289                 catch (InstantiationException ie) {
290                     _log.error(verifyProcesses[i] + " cannot be initiated");
291                 }
292             }
293         }
294 
295         PropsValues.INDEX_READ_ONLY = tempIndexReadOnly;
296 
297         // Update release
298 
299         ReleaseLocalServiceUtil.updateRelease(verified);
300     }
301 
302     private static final String _DELETE_TEMP_IMAGES_1 =
303         "DELETE FROM Image WHERE imageId IN (SELECT articleImageId FROM " +
304             "JournalArticleImage WHERE tempImage = TRUE)";
305 
306     private static final String _DELETE_TEMP_IMAGES_2 =
307         "DELETE FROM JournalArticleImage where tempImage = TRUE";
308 
309     private static Log _log = LogFactoryUtil.getLog(StartupAction.class);
310 
311 }