1
14
15 package com.liferay.portal.service.impl;
16
17 import com.liferay.portal.OldServiceComponentException;
18 import com.liferay.portal.PortalException;
19 import com.liferay.portal.SystemException;
20 import com.liferay.portal.kernel.cache.CacheRegistry;
21 import com.liferay.portal.kernel.dao.db.DB;
22 import com.liferay.portal.kernel.dao.db.DBFactoryUtil;
23 import com.liferay.portal.kernel.dao.orm.EntityCacheUtil;
24 import com.liferay.portal.kernel.dao.orm.FinderCacheUtil;
25 import com.liferay.portal.kernel.dao.shard.ShardUtil;
26 import com.liferay.portal.kernel.log.Log;
27 import com.liferay.portal.kernel.log.LogFactoryUtil;
28 import com.liferay.portal.kernel.upgrade.util.UpgradeTable;
29 import com.liferay.portal.kernel.upgrade.util.UpgradeTableFactoryUtil;
30 import com.liferay.portal.kernel.util.HttpUtil;
31 import com.liferay.portal.kernel.util.StringPool;
32 import com.liferay.portal.kernel.util.StringUtil;
33 import com.liferay.portal.kernel.xml.Document;
34 import com.liferay.portal.kernel.xml.DocumentException;
35 import com.liferay.portal.kernel.xml.Element;
36 import com.liferay.portal.kernel.xml.SAXReaderUtil;
37 import com.liferay.portal.model.Company;
38 import com.liferay.portal.model.ModelHintsUtil;
39 import com.liferay.portal.model.ServiceComponent;
40 import com.liferay.portal.service.base.ServiceComponentLocalServiceBaseImpl;
41 import com.liferay.portal.tools.servicebuilder.Entity;
42 import com.liferay.portal.util.PropsValues;
43
44 import java.io.IOException;
45 import java.io.InputStream;
46
47 import java.lang.reflect.Field;
48
49 import java.util.ArrayList;
50 import java.util.List;
51
52 import javax.servlet.ServletContext;
53
54
60 public class ServiceComponentLocalServiceImpl
61 extends ServiceComponentLocalServiceBaseImpl {
62
63 public void destroyServiceComponent(
64 ServletContext servletContext, ClassLoader classLoader)
65 throws SystemException {
66
67 try {
68 clearCacheRegistry(servletContext);
69 }
70 catch (Exception e) {
71 throw new SystemException(e);
72 }
73 }
74
75 public ServiceComponent initServiceComponent(
76 ServletContext servletContext, ClassLoader classLoader,
77 String buildNamespace, long buildNumber, long buildDate,
78 boolean buildAutoUpgrade)
79 throws PortalException, SystemException {
80
81 try {
82 ModelHintsUtil.read(
83 classLoader, "META-INF/portlet-model-hints.xml");
84 }
85 catch (Exception e) {
86 throw new SystemException(e);
87 }
88
89 try {
90 ModelHintsUtil.read(
91 classLoader, "META-INF/portlet-model-hints-ext.xml");
92 }
93 catch (Exception e) {
94 throw new SystemException(e);
95 }
96
97 ServiceComponent serviceComponent = null;
98 ServiceComponent previousServiceComponent = null;
99
100 List<ServiceComponent> serviceComponents =
101 serviceComponentPersistence.findByBuildNamespace(
102 buildNamespace, 0, 1);
103
104 if (serviceComponents.size() == 0) {
105 long serviceComponentId = counterLocalService.increment();
106
107 serviceComponent = serviceComponentPersistence.create(
108 serviceComponentId);
109
110 serviceComponent.setBuildNamespace(buildNamespace);
111 serviceComponent.setBuildNumber(buildNumber);
112 serviceComponent.setBuildDate(buildDate);
113 }
114 else {
115 serviceComponent = serviceComponents.get(0);
116
117 if (serviceComponent.getBuildNumber() < buildNumber) {
118 previousServiceComponent = serviceComponent;
119
120 long serviceComponentId = counterLocalService.increment();
121
122 serviceComponent = serviceComponentPersistence.create(
123 serviceComponentId);
124
125 serviceComponent.setBuildNamespace(buildNamespace);
126 serviceComponent.setBuildNumber(buildNumber);
127 serviceComponent.setBuildDate(buildDate);
128 }
129 else if (serviceComponent.getBuildNumber() > buildNumber) {
130 throw new OldServiceComponentException(
131 "Build namespace " + buildNamespace + " has build number " +
132 serviceComponent.getBuildNumber() +
133 " which is newer than " + buildNumber);
134 }
135 else {
136 return serviceComponent;
137 }
138 }
139
140 try {
141 Document document = SAXReaderUtil.createDocument(StringPool.UTF8);
142
143 Element dataElement = document.addElement("data");
144
145 String tablesSQL = HttpUtil.URLtoString(servletContext.getResource(
146 "/WEB-INF/sql/tables.sql"));
147
148 dataElement.addElement("tables-sql").addCDATA(tablesSQL);
149
150 String sequencesSQL = HttpUtil.URLtoString(
151 servletContext.getResource("/WEB-INF/sql/sequences.sql"));
152
153 dataElement.addElement("sequences-sql").addCDATA(sequencesSQL);
154
155 String indexesSQL = HttpUtil.URLtoString(servletContext.getResource(
156 "/WEB-INF/sql/indexes.sql"));
157
158 dataElement.addElement("indexes-sql").addCDATA(indexesSQL);
159
160 String dataXML = document.formattedString();
161
162 serviceComponent.setData(dataXML);
163
164 serviceComponentPersistence.update(serviceComponent, false);
165
166 serviceComponentLocalService.upgradeDB(
167 classLoader, buildNamespace, buildNumber, buildAutoUpgrade,
168 previousServiceComponent, tablesSQL, sequencesSQL, indexesSQL);
169
170 removeOldServiceComponents(buildNamespace);
171
172 return serviceComponent;
173 }
174 catch (Exception e) {
175 throw new SystemException(e);
176 }
177 }
178
179 public void upgradeDB(
180 ClassLoader classLoader, String buildNamespace, long buildNumber,
181 boolean buildAutoUpgrade, ServiceComponent previousServiceComponent,
182 String tablesSQL, String sequencesSQL, String indexesSQL)
183 throws Exception {
184
185 DB db = DBFactoryUtil.getDB();
186
187 if (previousServiceComponent == null) {
188 if (_log.isInfoEnabled()) {
189 _log.info("Running " + buildNamespace + " SQL scripts");
190 }
191
192 db.runSQLTemplateString(tablesSQL, true, false);
193 db.runSQLTemplateString(sequencesSQL, true, false);
194 db.runSQLTemplateString(indexesSQL, true, false);
195 }
196 else if (buildAutoUpgrade) {
197 if (_log.isInfoEnabled()) {
198 _log.info(
199 "Upgrading " + buildNamespace +
200 " database to build number " + buildNumber);
201 }
202
203 if (!tablesSQL.equals(
204 previousServiceComponent.getTablesSQL())) {
205
206 if (_log.isInfoEnabled()) {
207 _log.info("Upgrading database with tables.sql");
208 }
209
210 db.runSQLTemplateString(tablesSQL, true, false);
211
212 upgradeModels(classLoader);
213 }
214
215 if (!sequencesSQL.equals(
216 previousServiceComponent.getSequencesSQL())) {
217
218 if (_log.isInfoEnabled()) {
219 _log.info("Upgrading database with sequences.sql");
220 }
221
222 db.runSQLTemplateString(sequencesSQL, true, false);
223 }
224
225 if (!indexesSQL.equals(
226 previousServiceComponent.getIndexesSQL())) {
227
228 if (_log.isInfoEnabled()) {
229 _log.info("Upgrading database with indexes.sql");
230 }
231
232 db.runSQLTemplateString(indexesSQL, true, false);
233 }
234 }
235 }
236
237 public void verifyDB() throws PortalException, SystemException {
238 Company defaultCompany = companyPersistence.findByWebId(
239 PropsValues.COMPANY_DEFAULT_WEB_ID);
240
241 ShardUtil.pushCompanyService(defaultCompany.getCompanyId());
242
243 List<ServiceComponent> serviceComponents = null;
244
245 try {
246 serviceComponents = serviceComponentPersistence.findAll();
247 }
248 finally {
249 ShardUtil.popCompanyService();
250 }
251
252 for (ServiceComponent serviceComponent : serviceComponents) {
253 String buildNamespace = serviceComponent.getBuildNamespace();
254 String tablesSQL = serviceComponent.getTablesSQL();
255 String sequencesSQL = serviceComponent.getSequencesSQL();
256 String indexesSQL = serviceComponent.getIndexesSQL();
257
258 try {
259 serviceComponentLocalService.upgradeDB(
260 null, buildNamespace, 0, false, null, tablesSQL,
261 sequencesSQL, indexesSQL);
262 }
263 catch (Exception e) {
264 _log.error(e, e);
265 }
266 }
267 }
268
269 protected void clearCacheRegistry(ServletContext servletContext)
270 throws DocumentException {
271
272 InputStream inputStream = servletContext.getResourceAsStream(
273 "/WEB-INF/classes/META-INF/portlet-hbm.xml");
274
275 if (inputStream == null) {
276 return;
277 }
278
279 Document document = SAXReaderUtil.read(inputStream);
280
281 Element rootElement = document.getRootElement();
282
283 List<Element> classElements = rootElement.elements("class");
284
285 for (Element classElement : classElements) {
286 String name = classElement.attributeValue("name");
287
288 CacheRegistry.unregister(name);
289 }
290
291 CacheRegistry.clear();
292
293 EntityCacheUtil.clearCache();
294 FinderCacheUtil.clearCache();
295 }
296
297 protected List<String> getModels(ClassLoader classLoader)
298 throws DocumentException, IOException {
299
300 List<String> models = new ArrayList<String>();
301
302 String xml = StringUtil.read(
303 classLoader, "META-INF/portlet-model-hints.xml");
304
305 models.addAll(getModels(xml));
306
307 try {
308 xml = StringUtil.read(
309 classLoader, "META-INF/portlet-model-hints-ext.xml");
310
311 models.addAll(getModels(xml));
312 }
313 catch (Exception e) {
314 if (_log.isInfoEnabled()) {
315 _log.info(
316 "No optional file META-INF/portlet-model-hints-ext.xml " +
317 "found");
318 }
319 }
320
321 return models;
322 }
323
324 protected List<String> getModels(String xml) throws DocumentException {
325 List<String> models = new ArrayList<String>();
326
327 Document document = SAXReaderUtil.read(xml);
328
329 Element rootElement = document.getRootElement();
330
331 List<Element> modelElements = rootElement.elements("model");
332
333 for (Element modelElement : modelElements) {
334 String name = modelElement.attributeValue("name");
335
336 models.add(name);
337 }
338
339 return models;
340 }
341
342 protected void upgradeModels(ClassLoader classLoader) throws Exception {
343 List<String> models = getModels(classLoader);
344
345 for (String name : models) {
346 int pos = name.lastIndexOf(".model.");
347
348 name =
349 name.substring(0, pos) + ".model.impl." +
350 name.substring(pos + 7) + "ModelImpl";
351
352 Class<?> modelClass = Class.forName(name, true, classLoader);
353
354 Field tableNameField = modelClass.getField("TABLE_NAME");
355 Field tableColumnsField = modelClass.getField("TABLE_COLUMNS");
356 Field tableSQLCreateField = modelClass.getField("TABLE_SQL_CREATE");
357 Field dataSourceField = modelClass.getField("DATA_SOURCE");
358
359 String tableName = (String)tableNameField.get(null);
360 Object[][] tableColumns = (Object[][])tableColumnsField.get(null);
361 String tableSQLCreate = (String)tableSQLCreateField.get(null);
362 String dataSource = (String)dataSourceField.get(null);
363
364 if (!dataSource.equals(Entity.DEFAULT_DATA_SOURCE)) {
365 continue;
366 }
367
368 UpgradeTable upgradeTable = UpgradeTableFactoryUtil.getUpgradeTable(
369 tableName, tableColumns);
370
371 upgradeTable.setCreateSQL(tableSQLCreate);
372
373 upgradeTable.updateTable();
374 }
375 }
376
377 protected void removeOldServiceComponents(String buildNamespace)
378 throws SystemException {
379
380 int serviceComponentsCount =
381 serviceComponentPersistence.countByBuildNamespace(buildNamespace);
382
383 if (serviceComponentsCount < _MAX_SERVICE_COMPONENTS) {
384 return;
385 }
386
387 List<ServiceComponent> serviceComponents =
388 serviceComponentPersistence.findByBuildNamespace(
389 buildNamespace, _MAX_SERVICE_COMPONENTS,
390 serviceComponentsCount);
391
392 for (int i = 0; i < serviceComponents.size(); i++) {
393 ServiceComponent serviceComponent = serviceComponents.get(i);
394
395 serviceComponentPersistence.remove(serviceComponent);
396 }
397 }
398
399 private static final int _MAX_SERVICE_COMPONENTS = 10;
400
401 private static Log _log = LogFactoryUtil.getLog(
402 ServiceComponentLocalServiceImpl.class);
403
404 }