001
014
015 package com.liferay.portal.service.impl;
016
017 import com.liferay.portal.OldServiceComponentException;
018 import com.liferay.portal.kernel.cache.CacheRegistryUtil;
019 import com.liferay.portal.kernel.dao.db.DB;
020 import com.liferay.portal.kernel.dao.db.DBFactoryUtil;
021 import com.liferay.portal.kernel.dao.orm.EntityCacheUtil;
022 import com.liferay.portal.kernel.dao.orm.FinderCacheUtil;
023 import com.liferay.portal.kernel.exception.PortalException;
024 import com.liferay.portal.kernel.exception.SystemException;
025 import com.liferay.portal.kernel.log.Log;
026 import com.liferay.portal.kernel.log.LogFactoryUtil;
027 import com.liferay.portal.kernel.upgrade.util.UpgradeTable;
028 import com.liferay.portal.kernel.upgrade.util.UpgradeTableFactoryUtil;
029 import com.liferay.portal.kernel.util.HttpUtil;
030 import com.liferay.portal.kernel.util.StringPool;
031 import com.liferay.portal.kernel.util.StringUtil;
032 import com.liferay.portal.kernel.xml.Document;
033 import com.liferay.portal.kernel.xml.DocumentException;
034 import com.liferay.portal.kernel.xml.Element;
035 import com.liferay.portal.kernel.xml.SAXReaderUtil;
036 import com.liferay.portal.model.ModelHintsUtil;
037 import com.liferay.portal.model.ServiceComponent;
038 import com.liferay.portal.security.lang.PortalSecurityManagerThreadLocal;
039 import com.liferay.portal.security.pacl.PACLPolicy;
040 import com.liferay.portal.security.pacl.PACLPolicyManager;
041 import com.liferay.portal.service.base.ServiceComponentLocalServiceBaseImpl;
042 import com.liferay.portal.tools.servicebuilder.Entity;
043
044 import java.io.IOException;
045 import java.io.InputStream;
046
047 import java.lang.reflect.Field;
048
049 import java.util.ArrayList;
050 import java.util.List;
051
052 import javax.servlet.ServletContext;
053
054
057 public class ServiceComponentLocalServiceImpl
058 extends ServiceComponentLocalServiceBaseImpl {
059
060 public void destroyServiceComponent(
061 ServletContext servletContext, ClassLoader classLoader)
062 throws SystemException {
063
064 try {
065 clearCacheRegistry(servletContext);
066 }
067 catch (Exception e) {
068 throw new SystemException(e);
069 }
070 }
071
072 public ServiceComponent initServiceComponent(
073 ServletContext servletContext, ClassLoader classLoader,
074 String buildNamespace, long buildNumber, long buildDate,
075 boolean buildAutoUpgrade)
076 throws PortalException, SystemException {
077
078 try {
079 ModelHintsUtil.read(
080 classLoader, "META-INF/portlet-model-hints.xml");
081 }
082 catch (Exception e) {
083 throw new SystemException(e);
084 }
085
086 try {
087 ModelHintsUtil.read(
088 classLoader, "META-INF/portlet-model-hints-ext.xml");
089 }
090 catch (Exception e) {
091 throw new SystemException(e);
092 }
093
094 ServiceComponent serviceComponent = null;
095 ServiceComponent previousServiceComponent = null;
096
097 List<ServiceComponent> serviceComponents =
098 serviceComponentPersistence.findByBuildNamespace(
099 buildNamespace, 0, 1);
100
101 if (serviceComponents.size() == 0) {
102 long serviceComponentId = counterLocalService.increment();
103
104 serviceComponent = serviceComponentPersistence.create(
105 serviceComponentId);
106
107 serviceComponent.setBuildNamespace(buildNamespace);
108 serviceComponent.setBuildNumber(buildNumber);
109 serviceComponent.setBuildDate(buildDate);
110 }
111 else {
112 serviceComponent = serviceComponents.get(0);
113
114 if (serviceComponent.getBuildNumber() < buildNumber) {
115 previousServiceComponent = serviceComponent;
116
117 long serviceComponentId = counterLocalService.increment();
118
119 serviceComponent = serviceComponentPersistence.create(
120 serviceComponentId);
121
122 serviceComponent.setBuildNamespace(buildNamespace);
123 serviceComponent.setBuildNumber(buildNumber);
124 serviceComponent.setBuildDate(buildDate);
125 }
126 else if (serviceComponent.getBuildNumber() > buildNumber) {
127 throw new OldServiceComponentException(
128 "Build namespace " + buildNamespace + " has build number " +
129 serviceComponent.getBuildNumber() +
130 " which is newer than " + buildNumber);
131 }
132 else {
133 return serviceComponent;
134 }
135 }
136
137 try {
138 Document document = SAXReaderUtil.createDocument(StringPool.UTF8);
139
140 Element dataElement = document.addElement("data");
141
142 String tablesSQL = HttpUtil.URLtoString(servletContext.getResource(
143 "/WEB-INF/sql/tables.sql"));
144
145 dataElement.addElement("tables-sql").addCDATA(tablesSQL);
146
147 String sequencesSQL = HttpUtil.URLtoString(
148 servletContext.getResource("/WEB-INF/sql/sequences.sql"));
149
150 dataElement.addElement("sequences-sql").addCDATA(sequencesSQL);
151
152 String indexesSQL = HttpUtil.URLtoString(servletContext.getResource(
153 "/WEB-INF/sql/indexes.sql"));
154
155 dataElement.addElement("indexes-sql").addCDATA(indexesSQL);
156
157 String dataXML = document.formattedString();
158
159 serviceComponent.setData(dataXML);
160
161 serviceComponentPersistence.update(serviceComponent, false);
162
163 serviceComponentLocalService.upgradeDB(
164 classLoader, buildNamespace, buildNumber, buildAutoUpgrade,
165 previousServiceComponent, tablesSQL, sequencesSQL, indexesSQL);
166
167 removeOldServiceComponents(buildNamespace);
168
169 return serviceComponent;
170 }
171 catch (Exception e) {
172 throw new SystemException(e);
173 }
174 }
175
176 public void upgradeDB(
177 ClassLoader classLoader, String buildNamespace, long buildNumber,
178 boolean buildAutoUpgrade, ServiceComponent previousServiceComponent,
179 String tablesSQL, String sequencesSQL, String indexesSQL)
180 throws Exception {
181
182 PACLPolicy previousPACLPolicy =
183 PortalSecurityManagerThreadLocal.getPACLPolicy();
184
185 boolean checkGetClassLoader =
186 PortalSecurityManagerThreadLocal.isCheckGetClassLoader();
187 boolean checkReadFile =
188 PortalSecurityManagerThreadLocal.isCheckReadFile();
189
190 try {
191 PACLPolicy paclPolicy = PACLPolicyManager.getPACLPolicy(
192 classLoader);
193
194 PortalSecurityManagerThreadLocal.setPACLPolicy(paclPolicy);
195
196 PortalSecurityManagerThreadLocal.setCheckGetClassLoader(false);
197 PortalSecurityManagerThreadLocal.setCheckReadFile(false);
198
199 doUpgradeDB(
200 classLoader, buildNamespace, buildNumber, buildAutoUpgrade,
201 previousServiceComponent, tablesSQL, sequencesSQL, indexesSQL);
202 }
203 finally {
204 PortalSecurityManagerThreadLocal.setPACLPolicy(previousPACLPolicy);
205
206 PortalSecurityManagerThreadLocal.setCheckGetClassLoader(
207 checkGetClassLoader);
208 PortalSecurityManagerThreadLocal.setCheckReadFile(checkReadFile);
209 }
210 }
211
212 public void verifyDB() throws SystemException {
213 List<ServiceComponent> serviceComponents =
214 serviceComponentPersistence.findAll();
215
216 for (ServiceComponent serviceComponent : serviceComponents) {
217 String buildNamespace = serviceComponent.getBuildNamespace();
218 String tablesSQL = serviceComponent.getTablesSQL();
219 String sequencesSQL = serviceComponent.getSequencesSQL();
220 String indexesSQL = serviceComponent.getIndexesSQL();
221
222 try {
223 serviceComponentLocalService.upgradeDB(
224 null, buildNamespace, 0, false, null, tablesSQL,
225 sequencesSQL, indexesSQL);
226 }
227 catch (Exception e) {
228 _log.error(e, e);
229 }
230 }
231 }
232
233 protected void clearCacheRegistry(ServletContext servletContext)
234 throws DocumentException {
235
236 InputStream inputStream = servletContext.getResourceAsStream(
237 "/WEB-INF/classes/META-INF/portlet-hbm.xml");
238
239 if (inputStream == null) {
240 return;
241 }
242
243 Document document = SAXReaderUtil.read(inputStream);
244
245 Element rootElement = document.getRootElement();
246
247 List<Element> classElements = rootElement.elements("class");
248
249 for (Element classElement : classElements) {
250 String name = classElement.attributeValue("name");
251
252 CacheRegistryUtil.unregister(name);
253 }
254
255 CacheRegistryUtil.clear();
256
257 EntityCacheUtil.clearCache();
258 FinderCacheUtil.clearCache();
259 }
260
261 protected void doUpgradeDB(
262 ClassLoader classLoader, String buildNamespace, long buildNumber,
263 boolean buildAutoUpgrade, ServiceComponent previousServiceComponent,
264 String tablesSQL, String sequencesSQL, String indexesSQL)
265 throws Exception {
266
267 DB db = DBFactoryUtil.getDB();
268
269 if (previousServiceComponent == null) {
270 if (_log.isInfoEnabled()) {
271 _log.info("Running " + buildNamespace + " SQL scripts");
272 }
273
274 db.runSQLTemplateString(tablesSQL, true, false);
275 db.runSQLTemplateString(sequencesSQL, true, false);
276 db.runSQLTemplateString(indexesSQL, true, false);
277 }
278 else if (buildAutoUpgrade) {
279 if (_log.isInfoEnabled()) {
280 _log.info(
281 "Upgrading " + buildNamespace +
282 " database to build number " + buildNumber);
283 }
284
285 if (!tablesSQL.equals(previousServiceComponent.getTablesSQL())) {
286 if (_log.isInfoEnabled()) {
287 _log.info("Upgrading database with tables.sql");
288 }
289
290 db.runSQLTemplateString(tablesSQL, true, false);
291
292 upgradeModels(classLoader);
293 }
294
295 if (!sequencesSQL.equals(
296 previousServiceComponent.getSequencesSQL())) {
297
298 if (_log.isInfoEnabled()) {
299 _log.info("Upgrading database with sequences.sql");
300 }
301
302 db.runSQLTemplateString(sequencesSQL, true, false);
303 }
304
305 if (!indexesSQL.equals(previousServiceComponent.getIndexesSQL())) {
306 if (_log.isInfoEnabled()) {
307 _log.info("Upgrading database with indexes.sql");
308 }
309
310 db.runSQLTemplateString(indexesSQL, true, false);
311 }
312 }
313 }
314
315 protected List<String> getModels(ClassLoader classLoader)
316 throws DocumentException, IOException {
317
318 List<String> models = new ArrayList<String>();
319
320 String xml = StringUtil.read(
321 classLoader, "META-INF/portlet-model-hints.xml");
322
323 models.addAll(getModels(xml));
324
325 try {
326 xml = StringUtil.read(
327 classLoader, "META-INF/portlet-model-hints-ext.xml");
328
329 models.addAll(getModels(xml));
330 }
331 catch (Exception e) {
332 if (_log.isInfoEnabled()) {
333 _log.info(
334 "No optional file META-INF/portlet-model-hints-ext.xml " +
335 "found");
336 }
337 }
338
339 return models;
340 }
341
342 protected List<String> getModels(String xml) throws DocumentException {
343 List<String> models = new ArrayList<String>();
344
345 Document document = SAXReaderUtil.read(xml);
346
347 Element rootElement = document.getRootElement();
348
349 List<Element> modelElements = rootElement.elements("model");
350
351 for (Element modelElement : modelElements) {
352 String name = modelElement.attributeValue("name");
353
354 models.add(name);
355 }
356
357 return models;
358 }
359
360 protected void removeOldServiceComponents(String buildNamespace)
361 throws SystemException {
362
363 int serviceComponentsCount =
364 serviceComponentPersistence.countByBuildNamespace(buildNamespace);
365
366 if (serviceComponentsCount < _MAX_SERVICE_COMPONENTS) {
367 return;
368 }
369
370 List<ServiceComponent> serviceComponents =
371 serviceComponentPersistence.findByBuildNamespace(
372 buildNamespace, _MAX_SERVICE_COMPONENTS,
373 serviceComponentsCount);
374
375 for (int i = 0; i < serviceComponents.size(); i++) {
376 ServiceComponent serviceComponent = serviceComponents.get(i);
377
378 serviceComponentPersistence.remove(serviceComponent);
379 }
380 }
381
382 protected void upgradeModels(ClassLoader classLoader) throws Exception {
383 List<String> models = getModels(classLoader);
384
385 for (String name : models) {
386 int pos = name.lastIndexOf(".model.");
387
388 name =
389 name.substring(0, pos) + ".model.impl." +
390 name.substring(pos + 7) + "ModelImpl";
391
392 Class<?> modelClass = Class.forName(name, true, classLoader);
393
394 Field tableNameField = modelClass.getField("TABLE_NAME");
395 Field tableColumnsField = modelClass.getField("TABLE_COLUMNS");
396 Field tableSQLCreateField = modelClass.getField("TABLE_SQL_CREATE");
397 Field dataSourceField = modelClass.getField("DATA_SOURCE");
398
399 String tableName = (String)tableNameField.get(null);
400 Object[][] tableColumns = (Object[][])tableColumnsField.get(null);
401 String tableSQLCreate = (String)tableSQLCreateField.get(null);
402 String dataSource = (String)dataSourceField.get(null);
403
404 if (!dataSource.equals(Entity.DEFAULT_DATA_SOURCE)) {
405 continue;
406 }
407
408 UpgradeTable upgradeTable = UpgradeTableFactoryUtil.getUpgradeTable(
409 tableName, tableColumns);
410
411 upgradeTable.setCreateSQL(tableSQLCreate);
412
413 upgradeTable.updateTable();
414 }
415 }
416
417 private static final int _MAX_SERVICE_COMPONENTS = 10;
418
419 private static Log _log = LogFactoryUtil.getLog(
420 ServiceComponentLocalServiceImpl.class);
421
422 }