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