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