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