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