001
014
015 package com.liferay.portal.upgrade.v7_0_0;
016
017 import com.liferay.portal.kernel.dao.jdbc.DataAccess;
018 import com.liferay.portal.kernel.language.LanguageUtil;
019 import com.liferay.portal.kernel.log.Log;
020 import com.liferay.portal.kernel.log.LogFactoryUtil;
021 import com.liferay.portal.kernel.upgrade.UpgradeProcess;
022 import com.liferay.portal.kernel.util.LocalizationUtil;
023 import com.liferay.portal.kernel.util.StringBundler;
024 import com.liferay.portal.kernel.util.StringPool;
025 import com.liferay.portal.kernel.util.StringUtil;
026 import com.liferay.portal.kernel.uuid.PortalUUIDUtil;
027 import com.liferay.portal.kernel.xml.Document;
028 import com.liferay.portal.kernel.xml.Element;
029 import com.liferay.portal.kernel.xml.SAXReaderUtil;
030 import com.liferay.portal.util.PortalUtil;
031 import com.liferay.portlet.dynamicdatamapping.model.DDMContent;
032 import com.liferay.portlet.dynamicdatamapping.model.DDMStorageLink;
033
034 import java.sql.Connection;
035 import java.sql.PreparedStatement;
036 import java.sql.ResultSet;
037 import java.sql.Timestamp;
038
039 import java.util.HashMap;
040 import java.util.HashSet;
041 import java.util.Locale;
042 import java.util.Map;
043 import java.util.Set;
044
045
048 public class UpgradeDynamicDataLists extends UpgradeProcess {
049
050 protected void addDDMContent(
051 String uuid_, long contentId, long groupId, long companyId,
052 long userId, String userName, Timestamp createDate,
053 Timestamp modifiedDate, String name, String description, String xml)
054 throws Exception {
055
056 Connection con = null;
057 PreparedStatement ps = null;
058
059 try {
060 con = DataAccess.getUpgradeOptimizedConnection();
061
062 StringBundler sb = new StringBundler(4);
063
064 sb.append("insert into DDMContent (uuid_, contentId, groupId, ");
065 sb.append("companyId, userId, userName, createDate, ");
066 sb.append("modifiedDate, name, description, xml) values (?, ?, ");
067 sb.append("?, ?, ?, ?, ?, ?, ?, ?, ?)");
068
069 String sql = sb.toString();
070
071 ps = con.prepareStatement(sql);
072
073 ps.setString(1, uuid_);
074 ps.setLong(2, contentId);
075 ps.setLong(3, groupId);
076 ps.setLong(4, companyId);
077 ps.setLong(5, userId);
078 ps.setString(6, userName);
079 ps.setTimestamp(7, createDate);
080 ps.setTimestamp(8, modifiedDate);
081 ps.setString(9, name);
082 ps.setString(10, description);
083 ps.setString(11, xml);
084
085 ps.executeUpdate();
086 }
087 catch (Exception e) {
088 _log.error("Unable to add dynamic data mapping content ", e);
089
090 throw e;
091 }
092 finally {
093 DataAccess.cleanUp(con, ps);
094 }
095 }
096
097 protected void addDynamicContentElements(
098 Element dynamicElementElement, String name, String data) {
099
100 Map<Locale, String> localizationMap =
101 LocalizationUtil.getLocalizationMap(data);
102
103 for (Map.Entry<Locale, String> entry : localizationMap.entrySet()) {
104 String[] values = StringUtil.split(entry.getValue());
105
106 if (name.startsWith(StringPool.UNDERLINE)) {
107 values = new String[] {entry.getValue()};
108 }
109
110 for (String value : values) {
111 Element dynamicContentElement =
112 dynamicElementElement.addElement("dynamic-content");
113
114 dynamicContentElement.addAttribute(
115 "language-id", LanguageUtil.getLanguageId(entry.getKey()));
116 dynamicContentElement.addCDATA(value.trim());
117 }
118 }
119 }
120
121 protected void deleteExpandoData(Set<Long> expandoRowIds) throws Exception {
122 Connection con = null;
123 PreparedStatement ps = null;
124 ResultSet rs = null;
125
126 try {
127 con = DataAccess.getUpgradeOptimizedConnection();
128
129 ps = con.prepareStatement(
130 "select tableId from ExpandoRow where " +
131 getExpandoRowIds(expandoRowIds) + " group by tableId");
132
133 int parameterIndex = 1;
134
135 for (long expandoRowId : expandoRowIds) {
136 ps.setLong(parameterIndex++, expandoRowId);
137 }
138
139 rs = ps.executeQuery();
140
141 while (rs.next()) {
142 long tableId = rs.getLong("tableId");
143
144 runSQL("delete from ExpandoTable where tableId = " + tableId);
145
146 runSQL("delete from ExpandoRow where tableId = " + tableId);
147
148 runSQL("delete from ExpandoColumn where tableId = " + tableId);
149
150 runSQL("delete from ExpandoValue where tableId = " + tableId);
151 }
152 }
153 finally {
154 DataAccess.cleanUp(con, ps, rs);
155 }
156 }
157
158 @Override
159 protected void doUpgrade() throws Exception {
160 setUpClassNameIds();
161
162 upgradeRecordVersions();
163 }
164
165 protected String getExpandoRowIds(Set<Long> expandoRowIds) {
166 StringBundler sb = new StringBundler((expandoRowIds.size() * 2) + 1);
167
168 sb.append(StringPool.OPEN_PARENTHESIS);
169
170 for (int i = 0; i < expandoRowIds.size(); i++) {
171 sb.append("rowId_ = ?");
172
173 if ((i + 1) < expandoRowIds.size()) {
174 sb.append(" OR ");
175 }
176 }
177
178 sb.append(StringPool.CLOSE_PARENTHESIS);
179
180 return sb.toString();
181 }
182
183 protected Map<String, String> getExpandoValuesMap(long expandoRowId)
184 throws Exception {
185
186 Connection con = null;
187 PreparedStatement ps = null;
188 ResultSet rs = null;
189
190 try {
191 con = DataAccess.getUpgradeOptimizedConnection();
192
193 StringBundler sb = new StringBundler(4);
194
195 sb.append("select ExpandoColumn.name, ExpandoValue.data_ from ");
196 sb.append("ExpandoValue inner join ExpandoColumn on ");
197 sb.append("ExpandoColumn.columnId = ExpandoValue.columnId where ");
198 sb.append("rowId_ = ?");
199
200 ps = con.prepareStatement(sb.toString());
201
202 ps.setLong(1, expandoRowId);
203
204 rs = ps.executeQuery();
205
206 Map<String, String> fieldsMap = new HashMap<String, String>();
207
208 while (rs.next()) {
209 String name = rs.getString("name");
210 String data_ = rs.getString("data_");
211
212 fieldsMap.put(name, data_);
213 }
214
215 return fieldsMap;
216 }
217 finally {
218 DataAccess.cleanUp(con, ps, rs);
219 }
220 }
221
222 protected String getUpgradeRecordVersionsSQL() {
223 StringBundler sb = new StringBundler(5);
224
225 sb.append("select DDLRecordVersion.* from DDLRecordVersion inner ");
226 sb.append("join DDLRecordSet on DDLRecordVersion.recordSetId = ");
227 sb.append("DDLRecordSet.recordSetId inner join DDMStructure on ");
228 sb.append("DDLRecordSet.ddmStructureId = DDMStructure.structureId ");
229 sb.append("where DDMStructure.storageType = 'expando'");
230
231 return sb.toString();
232 }
233
234 protected void setUpClassNameIds() {
235 _ddmContentClassNameId = PortalUtil.getClassNameId(DDMContent.class);
236
237 _expandoStorageAdapterClassNameId = PortalUtil.getClassNameId(
238 "com.liferay.portlet.dynamicdatamapping.storage." +
239 "ExpandoStorageAdapter");
240 }
241
242 protected String toXML(Map<String, String> expandoValuesMap) {
243 Document document = SAXReaderUtil.createDocument();
244
245 Element rootElement = document.addElement("root");
246
247 for (Map.Entry<String, String> entry : expandoValuesMap.entrySet()) {
248 Element dynamicElementElement = rootElement.addElement(
249 "dynamic-element");
250
251 String name = entry.getKey();
252 String data = entry.getValue();
253
254 dynamicElementElement.addAttribute("name", name);
255 dynamicElementElement.addAttribute(
256 "default-language-id",
257 LocalizationUtil.getDefaultLanguageId(data));
258
259 addDynamicContentElements(dynamicElementElement, name, data);
260 }
261
262 return document.asXML();
263 }
264
265 protected void updateDDMStorageLink(
266 long oldClassNameId, long oldClassPK, long newClassNameId,
267 long newClassPK)
268 throws Exception {
269
270 runSQL(
271 "update DDMStorageLink set classNameId = " + newClassNameId + ", " +
272 "classPK = " + newClassPK + " where classNameId = " +
273 oldClassNameId + " and classPK = " + oldClassPK);
274 }
275
276 protected void updateDDMStructureStorageType() throws Exception {
277 runSQL(
278 "update DDMStructure set storageType = 'xml' where storageType = " +
279 "'expando'");
280 }
281
282 protected void updateRecordDDMStorageId(
283 long recordId, String version, long ddmContentId)
284 throws Exception {
285
286 runSQL(
287 "update DDLRecord set ddmStorageId = " + ddmContentId +
288 " where recordId = " + recordId + " and version = '" +
289 version + "'");
290 }
291
292 protected void updateRecordVersionDDMStorageId(
293 long recordVersionId, long DDMStorageId)
294 throws Exception {
295
296 runSQL(
297 "update DDLRecordVersion set ddmStorageId = " + DDMStorageId +
298 " where recordVersionId = " + recordVersionId);
299 }
300
301 protected void upgradeRecordVersions() throws Exception {
302 Connection con = null;
303 PreparedStatement ps = null;
304 ResultSet rs = null;
305
306 try {
307 con = DataAccess.getUpgradeOptimizedConnection();
308
309 String sql = getUpgradeRecordVersionsSQL();
310
311 ps = con.prepareStatement(sql);
312
313 rs = ps.executeQuery();
314
315 Set<Long> ddmStorageIds = new HashSet<Long>();
316
317 while (rs.next()) {
318 long recordVersionId = rs.getLong("recordVersionId");
319 long groupId = rs.getLong("groupId");
320 long companyId = rs.getLong("companyId");
321 long userId = rs.getLong("userId");
322 String userName = rs.getString("userName");
323 Timestamp createDate = rs.getTimestamp("createDate");
324 long ddmStorageId = rs.getLong("DDMStorageId");
325 long recordId = rs.getLong("recordId");
326 String version = rs.getString("version");
327
328 long ddmContentId = increment();
329
330 Map<String, String> expandoValuesMap = getExpandoValuesMap(
331 ddmStorageId);
332
333 String xml = toXML(expandoValuesMap);
334
335 addDDMContent(
336 PortalUUIDUtil.generate(), ddmContentId, groupId, companyId,
337 userId, userName, createDate, createDate,
338 DDMStorageLink.class.getName(), null, xml);
339
340 updateRecordVersionDDMStorageId(recordVersionId, ddmContentId);
341
342 updateRecordDDMStorageId(recordId, version, ddmContentId);
343
344 updateDDMStorageLink(
345 _expandoStorageAdapterClassNameId, ddmStorageId,
346 _ddmContentClassNameId, ddmContentId);
347
348 ddmStorageIds.add(ddmStorageId);
349 }
350
351 if (ddmStorageIds.isEmpty()) {
352 return;
353 }
354
355 updateDDMStructureStorageType();
356
357 deleteExpandoData(ddmStorageIds);
358 }
359 finally {
360 DataAccess.cleanUp(con, ps, rs);
361 }
362 }
363
364 private static final Log _log = LogFactoryUtil.getLog(
365 UpgradeDynamicDataLists.class);
366
367 private long _ddmContentClassNameId;
368 private long _expandoStorageAdapterClassNameId;
369
370 }