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