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