001
014
015 package com.liferay.portal.service.impl;
016
017 import com.liferay.portal.OldServiceComponentException;
018 import com.liferay.portal.kernel.cache.CacheRegistryUtil;
019 import com.liferay.portal.kernel.dao.db.DB;
020 import com.liferay.portal.kernel.dao.db.DBFactoryUtil;
021 import com.liferay.portal.kernel.dao.orm.EntityCacheUtil;
022 import com.liferay.portal.kernel.dao.orm.FinderCacheUtil;
023 import com.liferay.portal.kernel.dao.shard.ShardUtil;
024 import com.liferay.portal.kernel.exception.PortalException;
025 import com.liferay.portal.kernel.exception.SystemException;
026 import com.liferay.portal.kernel.log.Log;
027 import com.liferay.portal.kernel.log.LogFactoryUtil;
028 import com.liferay.portal.kernel.upgrade.util.UpgradeTable;
029 import com.liferay.portal.kernel.upgrade.util.UpgradeTableFactoryUtil;
030 import com.liferay.portal.kernel.util.HttpUtil;
031 import com.liferay.portal.kernel.util.StringPool;
032 import com.liferay.portal.kernel.util.StringUtil;
033 import com.liferay.portal.kernel.xml.Document;
034 import com.liferay.portal.kernel.xml.DocumentException;
035 import com.liferay.portal.kernel.xml.Element;
036 import com.liferay.portal.kernel.xml.SAXReaderUtil;
037 import com.liferay.portal.model.Company;
038 import com.liferay.portal.model.ModelHintsUtil;
039 import com.liferay.portal.model.ServiceComponent;
040 import com.liferay.portal.service.base.ServiceComponentLocalServiceBaseImpl;
041 import com.liferay.portal.tools.servicebuilder.Entity;
042 import com.liferay.portal.util.PropsValues;
043
044 import java.io.IOException;
045 import java.io.InputStream;
046
047 import java.lang.reflect.Field;
048
049 import java.util.ArrayList;
050 import java.util.Iterator;
051 import java.util.List;
052
053 import javax.servlet.ServletContext;
054
055
058 public class ServiceComponentLocalServiceImpl
059 extends ServiceComponentLocalServiceBaseImpl {
060
061 public void destroyServiceComponent(
062 ServletContext servletContext, ClassLoader classLoader)
063 throws SystemException {
064
065 try {
066 clearCacheRegistry(servletContext);
067 }
068 catch (Exception e) {
069 throw new SystemException(e);
070 }
071 }
072
073 public ServiceComponent initServiceComponent(
074 ServletContext servletContext, ClassLoader classLoader,
075 String buildNamespace, long buildNumber, long buildDate,
076 boolean buildAutoUpgrade)
077 throws PortalException, SystemException {
078
079 try {
080 ModelHintsUtil.read(
081 classLoader, "META-INF/portlet-model-hints.xml");
082 }
083 catch (Exception e) {
084 throw new SystemException(e);
085 }
086
087 try {
088 ModelHintsUtil.read(
089 classLoader, "META-INF/portlet-model-hints-ext.xml");
090 }
091 catch (Exception e) {
092 throw new SystemException(e);
093 }
094
095 ServiceComponent serviceComponent = null;
096 ServiceComponent previousServiceComponent = null;
097
098 List<ServiceComponent> serviceComponents =
099 serviceComponentPersistence.findByBuildNamespace(
100 buildNamespace, 0, 1);
101
102 if (serviceComponents.size() == 0) {
103 long serviceComponentId = counterLocalService.increment();
104
105 serviceComponent = serviceComponentPersistence.create(
106 serviceComponentId);
107
108 serviceComponent.setBuildNamespace(buildNamespace);
109 serviceComponent.setBuildNumber(buildNumber);
110 serviceComponent.setBuildDate(buildDate);
111 }
112 else {
113 serviceComponent = serviceComponents.get(0);
114
115 if (serviceComponent.getBuildNumber() < buildNumber) {
116 previousServiceComponent = serviceComponent;
117
118 long serviceComponentId = counterLocalService.increment();
119
120 serviceComponent = serviceComponentPersistence.create(
121 serviceComponentId);
122
123 serviceComponent.setBuildNamespace(buildNamespace);
124 serviceComponent.setBuildNumber(buildNumber);
125 serviceComponent.setBuildDate(buildDate);
126 }
127 else if (serviceComponent.getBuildNumber() > buildNumber) {
128 throw new OldServiceComponentException(
129 "Build namespace " + buildNamespace + " has build number " +
130 serviceComponent.getBuildNumber() +
131 " which is newer than " + buildNumber);
132 }
133 else {
134 return serviceComponent;
135 }
136 }
137
138 try {
139 Document doc = SAXReaderUtil.createDocument(StringPool.UTF8);
140
141 Element data = doc.addElement("data");
142
143 String tablesSQL = HttpUtil.URLtoString(servletContext.getResource(
144 "/WEB-INF/sql/tables.sql"));
145
146 data.addElement("tables-sql").addCDATA(tablesSQL);
147
148 String sequencesSQL = HttpUtil.URLtoString(
149 servletContext.getResource("/WEB-INF/sql/sequences.sql"));
150
151 data.addElement("sequences-sql").addCDATA(sequencesSQL);
152
153 String indexesSQL = HttpUtil.URLtoString(servletContext.getResource(
154 "/WEB-INF/sql/indexes.sql"));
155
156 data.addElement("indexes-sql").addCDATA(indexesSQL);
157
158 String dataXML = doc.formattedString();
159
160 serviceComponent.setData(dataXML);
161
162 serviceComponentPersistence.update(serviceComponent, false);
163
164 serviceComponentLocalService.upgradeDB(
165 classLoader, buildNamespace, buildNumber, buildAutoUpgrade,
166 previousServiceComponent, tablesSQL, sequencesSQL, indexesSQL);
167
168 removeOldServiceComponents(buildNamespace);
169
170 return serviceComponent;
171 }
172 catch (Exception e) {
173 throw new SystemException(e);
174 }
175 }
176
177 public void upgradeDB(
178 ClassLoader classLoader, String buildNamespace, long buildNumber,
179 boolean buildAutoUpgrade, ServiceComponent previousServiceComponent,
180 String tablesSQL, String sequencesSQL, String indexesSQL)
181 throws Exception {
182
183 DB db = DBFactoryUtil.getDB();
184
185 if (previousServiceComponent == null) {
186 if (_log.isInfoEnabled()) {
187 _log.info("Running " + buildNamespace + " SQL scripts");
188 }
189
190 db.runSQLTemplateString(tablesSQL, true, false);
191 db.runSQLTemplateString(sequencesSQL, true, false);
192 db.runSQLTemplateString(indexesSQL, true, false);
193 }
194 else if (buildAutoUpgrade) {
195 if (_log.isInfoEnabled()) {
196 _log.info(
197 "Upgrading " + buildNamespace +
198 " database to build number " + buildNumber);
199 }
200
201 if (!tablesSQL.equals(
202 previousServiceComponent.getTablesSQL())) {
203
204 if (_log.isInfoEnabled()) {
205 _log.info("Upgrading database with tables.sql");
206 }
207
208 db.runSQLTemplateString(tablesSQL, true, false);
209
210 upgradeModels(classLoader);
211 }
212
213 if (!sequencesSQL.equals(
214 previousServiceComponent.getSequencesSQL())) {
215
216 if (_log.isInfoEnabled()) {
217 _log.info("Upgrading database with sequences.sql");
218 }
219
220 db.runSQLTemplateString(sequencesSQL, true, false);
221 }
222
223 if (!indexesSQL.equals(
224 previousServiceComponent.getIndexesSQL())) {
225
226 if (_log.isInfoEnabled()) {
227 _log.info("Upgrading database with indexes.sql");
228 }
229
230 db.runSQLTemplateString(indexesSQL, true, false);
231 }
232 }
233 }
234
235 public void verifyDB() throws PortalException, SystemException {
236 Company defaultCompany = companyPersistence.findByWebId(
237 PropsValues.COMPANY_DEFAULT_WEB_ID);
238
239 ShardUtil.pushCompanyService(defaultCompany.getCompanyId());
240
241 List<ServiceComponent> serviceComponents = null;
242
243 try {
244 serviceComponents = serviceComponentPersistence.findAll();
245 }
246 finally {
247 ShardUtil.popCompanyService();
248 }
249
250 for (ServiceComponent serviceComponent : serviceComponents) {
251 String buildNamespace = serviceComponent.getBuildNamespace();
252 String tablesSQL = serviceComponent.getTablesSQL();
253 String sequencesSQL = serviceComponent.getSequencesSQL();
254 String indexesSQL = serviceComponent.getIndexesSQL();
255
256 try {
257 serviceComponentLocalService.upgradeDB(
258 null, buildNamespace, 0, false, null, tablesSQL,
259 sequencesSQL, indexesSQL);
260 }
261 catch (Exception e) {
262 _log.error(e, e);
263 }
264 }
265 }
266
267 protected void clearCacheRegistry(ServletContext servletContext)
268 throws DocumentException {
269
270 InputStream is = servletContext.getResourceAsStream(
271 "/WEB-INF/classes/META-INF/portlet-hbm.xml");
272
273 if (is == null) {
274 return;
275 }
276
277 Document doc = SAXReaderUtil.read(is);
278
279 Element root = doc.getRootElement();
280
281 List<Element> classEls = root.elements("class");
282
283 for (Element classEl : classEls) {
284 String name = classEl.attributeValue("name");
285
286 CacheRegistryUtil.unregister(name);
287 }
288
289 CacheRegistryUtil.clear();
290
291 EntityCacheUtil.clearCache();
292 FinderCacheUtil.clearCache();
293 }
294
295 protected List<String> getModels(ClassLoader classLoader)
296 throws DocumentException, IOException {
297
298 List<String> models = new ArrayList<String>();
299
300 String xml = StringUtil.read(
301 classLoader, "META-INF/portlet-model-hints.xml");
302
303 models.addAll(getModels(xml));
304
305 try {
306 xml = StringUtil.read(
307 classLoader, "META-INF/portlet-model-hints-ext.xml");
308
309 models.addAll(getModels(xml));
310 }
311 catch (Exception e) {
312 if (_log.isInfoEnabled()) {
313 _log.info(
314 "No optional file META-INF/portlet-model-hints-ext.xml " +
315 "found");
316 }
317 }
318
319 return models;
320 }
321
322 protected List<String> getModels(String xml) throws DocumentException {
323 List<String> models = new ArrayList<String>();
324
325 Document doc = SAXReaderUtil.read(xml);
326
327 Element root = doc.getRootElement();
328
329 Iterator<Element> itr = root.elements("model").iterator();
330
331 while (itr.hasNext()) {
332 Element modelEl = itr.next();
333
334 String name = modelEl.attributeValue("name");
335
336 models.add(name);
337 }
338
339 return models;
340 }
341
342 protected void upgradeModels(ClassLoader classLoader) throws Exception {
343 List<String> models = getModels(classLoader);
344
345 for (String name : models) {
346 int pos = name.lastIndexOf(".model.");
347
348 name =
349 name.substring(0, pos) + ".model.impl." +
350 name.substring(pos + 7) + "ModelImpl";
351
352 Class<?> modelClass = Class.forName(name, true, classLoader);
353
354 Field tableNameField = modelClass.getField("TABLE_NAME");
355 Field tableColumnsField = modelClass.getField("TABLE_COLUMNS");
356 Field tableSQLCreateField = modelClass.getField("TABLE_SQL_CREATE");
357 Field dataSourceField = modelClass.getField("DATA_SOURCE");
358
359 String tableName = (String)tableNameField.get(null);
360 Object[][] tableColumns = (Object[][])tableColumnsField.get(null);
361 String tableSQLCreate = (String)tableSQLCreateField.get(null);
362 String dataSource = (String)dataSourceField.get(null);
363
364 if (!dataSource.equals(Entity.DEFAULT_DATA_SOURCE)) {
365 continue;
366 }
367
368 UpgradeTable upgradeTable = UpgradeTableFactoryUtil.getUpgradeTable(
369 tableName, tableColumns);
370
371 upgradeTable.setCreateSQL(tableSQLCreate);
372
373 upgradeTable.updateTable();
374 }
375 }
376
377 protected void removeOldServiceComponents(String buildNamespace)
378 throws SystemException {
379
380 int serviceComponentsCount =
381 serviceComponentPersistence.countByBuildNamespace(buildNamespace);
382
383 if (serviceComponentsCount < _MAX_SERVICE_COMPONENTS) {
384 return;
385 }
386
387 List<ServiceComponent> serviceComponents =
388 serviceComponentPersistence.findByBuildNamespace(
389 buildNamespace, _MAX_SERVICE_COMPONENTS,
390 serviceComponentsCount);
391
392 for (int i = 0; i < serviceComponents.size(); i++) {
393 ServiceComponent serviceComponent = serviceComponents.get(i);
394
395 serviceComponentPersistence.remove(serviceComponent);
396 }
397 }
398
399 private static final int _MAX_SERVICE_COMPONENTS = 10;
400
401 private static Log _log = LogFactoryUtil.getLog(
402 ServiceComponentLocalServiceImpl.class);
403
404 }