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