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