001    /**
002     * Copyright (c) 2000-2013 Liferay, Inc. All rights reserved.
003     *
004     * This library is free software; you can redistribute it and/or modify it under
005     * the terms of the GNU Lesser General Public License as published by the Free
006     * Software Foundation; either version 2.1 of the License, or (at your option)
007     * any later version.
008     *
009     * This library is distributed in the hope that it will be useful, but WITHOUT
010     * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
011     * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
012     * details.
013     */
014    
015    package com.liferay.portal.upgrade.v6_0_12;
016    
017    import com.liferay.portal.kernel.dao.jdbc.DataAccess;
018    import com.liferay.portal.kernel.io.unsync.UnsyncByteArrayInputStream;
019    import com.liferay.portal.kernel.io.unsync.UnsyncByteArrayOutputStream;
020    import com.liferay.portal.kernel.json.JSONFactoryUtil;
021    import com.liferay.portal.kernel.messaging.DestinationNames;
022    import com.liferay.portal.kernel.messaging.Message;
023    import com.liferay.portal.kernel.scheduler.JobState;
024    import com.liferay.portal.kernel.scheduler.SchedulerEngine;
025    import com.liferay.portal.kernel.scheduler.StorageType;
026    import com.liferay.portal.kernel.scheduler.TriggerState;
027    import com.liferay.portal.kernel.upgrade.UpgradeProcess;
028    import com.liferay.portal.util.PropsValues;
029    
030    import java.io.ObjectInputStream;
031    import java.io.ObjectOutputStream;
032    
033    import java.sql.Connection;
034    import java.sql.PreparedStatement;
035    import java.sql.ResultSet;
036    
037    import java.util.ArrayList;
038    import java.util.List;
039    import java.util.Map;
040    
041    /**
042     * @author Tina Tian
043     */
044    public class UpgradeScheduler extends UpgradeProcess {
045    
046            protected void deleteJob(String jobName, String jobGroup) throws Exception {
047                    runSQL(
048                            "delete from QUARTZ_CRON_TRIGGERS where TRIGGER_NAME = '" +
049                                    jobName + "' and TRIGGER_GROUP = '" + jobGroup + "'");
050    
051                    runSQL(
052                            "delete from QUARTZ_JOB_DETAILS where JOB_NAME = '" +
053                                    jobName + "' and JOB_GROUP = '" + jobGroup + "'");
054    
055                    runSQL(
056                            "delete from QUARTZ_SIMPLE_TRIGGERS where TRIGGER_NAME = '" +
057                                    jobName + "' and TRIGGER_GROUP = '" + jobGroup + "'");
058    
059                    runSQL(
060                            "delete from QUARTZ_TRIGGERS where TRIGGER_NAME = '" +
061                                    jobName + "' and TRIGGER_GROUP = '" + jobGroup + "'");
062            }
063    
064            @Override
065            protected void doUpgrade() throws Exception {
066                    if (!PropsValues.SCHEDULER_ENABLED) {
067                            return;
068                    }
069    
070                    List<Object[]> arrays = getUpgradeQuartzData();
071    
072                    if (arrays.isEmpty()) {
073                            return;
074                    }
075    
076                    for (Object[] array : arrays) {
077                            String jobName = (String)array[0];
078                            String jobGroup = (String)array[1];
079                            byte[] jobData = (byte[])array[2];
080    
081                            if (jobData == null) {
082                                    deleteJob(jobName, jobGroup);
083                            }
084                            else {
085                                    updateJobDetail(jobName, jobGroup, jobData);
086                            }
087                    }
088            }
089    
090            protected List<Object[]> getUpgradeQuartzData() throws Exception {
091                    Connection con = null;
092                    PreparedStatement ps = null;
093                    ResultSet rs = null;
094    
095                    List<Object[]> arrays = new ArrayList<Object[]>();
096    
097                    try {
098                            con = DataAccess.getUpgradeOptimizedConnection();
099    
100                            ps = con.prepareStatement(
101                                    "select JOB_NAME, JOB_GROUP, JOB_DATA from QUARTZ_JOB_DETAILS");
102    
103                            rs = ps.executeQuery();
104    
105                            while (rs.next()) {
106                                    String jobName = rs.getString("JOB_NAME");
107                                    String jobGroup = rs.getString("JOB_GROUP");
108                                    byte[] jobData = rs.getBytes("JOB_DATA");
109    
110                                    Object[] array = new Object[3];
111    
112                                    if (jobData == null) {
113                                            array[0] = jobName;
114                                            array[1] = jobGroup;
115                                            array[2] = null;
116    
117                                            arrays.add(array);
118    
119                                            continue;
120                                    }
121    
122                                    ObjectInputStream objectInputStream =
123                                            new ObjectInputStream(
124                                                    new UnsyncByteArrayInputStream(jobData));
125    
126                                    Map<Object, Object> jobDataMap =
127                                            (Map<Object, Object>)objectInputStream.readObject();
128    
129                                    objectInputStream.close();
130    
131                                    String destinationName = (String)jobDataMap.get(
132                                            SchedulerEngine.DESTINATION_NAME);
133    
134                                    if (!destinationName.equals(
135                                                    DestinationNames.LAYOUTS_LOCAL_PUBLISHER) &&
136                                            !destinationName.equals(
137                                                    DestinationNames.LAYOUTS_REMOTE_PUBLISHER)) {
138    
139                                            array[0] = jobName;
140                                            array[1] = jobGroup;
141                                            array[2] = null;
142    
143                                            arrays.add(array);
144    
145                                            continue;
146                                    }
147    
148                                    JobState jobState = (JobState)jobDataMap.get(
149                                            SchedulerEngine.JOB_STATE);
150    
151                                    if (jobState == null) {
152                                            jobDataMap.put(
153                                                    SchedulerEngine.STORAGE_TYPE,
154                                                    StorageType.PERSISTED.toString());
155    
156                                            String messageJSON = (String)jobDataMap.get(
157                                                    SchedulerEngine.MESSAGE);
158    
159                                            Message message = (Message)JSONFactoryUtil.deserialize(
160                                                    messageJSON);;
161    
162                                            int exceptionsMaxSize = message.getInteger(
163                                                    SchedulerEngine.EXCEPTIONS_MAX_SIZE);
164    
165                                            jobState = new JobState(
166                                                    TriggerState.NORMAL, exceptionsMaxSize);
167    
168                                            jobDataMap.put(SchedulerEngine.JOB_STATE, jobState);
169                                    }
170    
171                                    UnsyncByteArrayOutputStream newJobDataOutputStream =
172                                            new UnsyncByteArrayOutputStream();
173                                    ObjectOutputStream objectOutputStream = new ObjectOutputStream(
174                                            newJobDataOutputStream);
175    
176                                    objectOutputStream.writeObject(jobDataMap);
177    
178                                    objectOutputStream.close();
179    
180                                    jobData = newJobDataOutputStream.toByteArray();
181    
182                                    array[0] = jobName;
183                                    array[1] = jobGroup;
184                                    array[2] = jobData;
185    
186                                    arrays.add(array);
187                            }
188                    }
189                    finally {
190                            DataAccess.cleanUp(con, ps, rs);
191                    }
192    
193                    return arrays;
194            }
195    
196            protected void updateJobDetail(
197                            String jobName, String jobGroup, byte[] jobData)
198                    throws Exception {
199    
200                    Connection con = null;
201                    PreparedStatement ps = null;
202                    ResultSet rs = null;
203    
204                    try {
205                            con = DataAccess.getUpgradeOptimizedConnection();
206    
207                            ps = con.prepareStatement(
208                                    "update QUARTZ_JOB_DETAILS set JOB_DATA = ? where JOB_NAME = " +
209                                            "? and JOB_GROUP = ?");
210    
211                            ps.setBytes(1, jobData);
212                            ps.setString(2, jobName);
213                            ps.setString(3, jobGroup);
214    
215                            ps.executeUpdate();
216                    }
217                    finally {
218                            DataAccess.cleanUp(con, ps, rs);
219                    }
220            }
221    
222    }