001    /**
002     * Copyright (c) 2000-2011 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_1_0;
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.JobStateSerializeUtil;
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)
048                    throws Exception {
049    
050                    runSQL(
051                            "delete from QUARTZ_CRON_TRIGGERS where TRIGGER_NAME = '" +
052                                    jobName + "' and TRIGGER_GROUP = '" + jobGroup + "'");
053    
054                    runSQL(
055                            "delete from QUARTZ_JOB_DETAILS where JOB_NAME = '" +
056                                    jobName + "' and JOB_GROUP = '" + jobGroup + "'");
057    
058                    runSQL(
059                            "delete from QUARTZ_SIMPLE_TRIGGERS where TRIGGER_NAME = '" +
060                                    jobName + "' and TRIGGER_GROUP = '" + jobGroup + "'");
061    
062                    runSQL(
063                            "delete from QUARTZ_TRIGGERS where TRIGGER_NAME = '" +
064                                    jobName + "' and TRIGGER_GROUP = '" + jobGroup + "'");
065            }
066    
067            @Override
068            protected void doUpgrade() throws Exception {
069                    if (!PropsValues.SCHEDULER_ENABLED) {
070                            return;
071                    }
072    
073                    List<Object[]> arrays = getUpgradeQuartzData();
074    
075                    if (arrays.isEmpty()) {
076                            return;
077                    }
078    
079                    for (Object[] array : arrays) {
080                            String jobName = (String)array[0];
081                            String jobGroup = (String)array[1];
082                            byte[] jobData = (byte[])array[2];
083    
084                            if (jobData == null) {
085                                    deleteJob(jobName, jobGroup);
086                            }
087                            else {
088                                    updateJobDetail(jobName, jobGroup, jobData);
089                            }
090                    }
091            }
092    
093            protected List<Object[]> getUpgradeQuartzData() throws Exception {
094                    Connection con = null;
095                    PreparedStatement ps = null;
096                    ResultSet rs = null;
097    
098                    try {
099                            con = DataAccess.getConnection();
100    
101                            ps = con.prepareStatement(
102                                    "select JOB_NAME, JOB_GROUP, JOB_DATA from QUARTZ_JOB_DETAILS");
103    
104                            rs = ps.executeQuery();
105    
106                            List<Object[]> arrays = new ArrayList<Object[]>();
107    
108                            while (rs.next()) {
109                                    String jobName = rs.getString("JOB_NAME");
110                                    String jobGroup = rs.getString("JOB_GROUP");
111                                    byte[] jobData = rs.getBytes("JOB_DATA");
112    
113                                    Object[] array = new Object[3];
114    
115                                    if (jobData == null) {
116                                            array[0] = jobName;
117                                            array[1] = jobGroup;
118                                            array[2] = null;
119    
120                                            arrays.add(array);
121    
122                                            continue;
123                                    }
124    
125                                    ObjectInputStream objectInputStream =
126                                            new ObjectInputStream(
127                                                    new UnsyncByteArrayInputStream(jobData));
128    
129                                    Map<Object, Object> jobDataMap =
130                                            (Map<Object, Object>)objectInputStream.readObject();
131    
132                                    objectInputStream.close();
133    
134                                    String destinationName = (String)jobDataMap.get(
135                                            SchedulerEngine.DESTINATION_NAME);
136    
137                                    if (!destinationName.equals(
138                                                    DestinationNames.LAYOUTS_LOCAL_PUBLISHER) &&
139                                            !destinationName.equals(
140                                                    DestinationNames.LAYOUTS_REMOTE_PUBLISHER)) {
141    
142                                            array[0] = jobName;
143                                            array[1] = jobGroup;
144                                            array[2] = null;
145    
146                                            arrays.add(array);
147    
148                                            continue;
149                                    }
150    
151                                    Map<String, Object> jobStateMap =
152                                            (Map<String, Object>)jobDataMap.get(
153                                                    SchedulerEngine.JOB_STATE);
154    
155                                    if (jobStateMap == null) {
156                                            jobDataMap.put(
157                                                    SchedulerEngine.STORAGE_TYPE,
158                                                    StorageType.PERSISTED.toString());
159    
160                                            String messageJSON = (String)jobDataMap.get(
161                                                    SchedulerEngine.MESSAGE);
162    
163                                            Message message = (Message)JSONFactoryUtil.deserialize(
164                                                    messageJSON);
165    
166                                            int exceptionsMaxSize = message.getInteger(
167                                                    SchedulerEngine.EXCEPTIONS_MAX_SIZE);
168    
169                                            JobState jobState = new JobState(
170                                                    TriggerState.NORMAL, exceptionsMaxSize);
171    
172                                            jobDataMap.put(
173                                                    SchedulerEngine.JOB_STATE,
174                                                    JobStateSerializeUtil.serialize(jobState));
175                                    }
176    
177                                    UnsyncByteArrayOutputStream newJobDataOutputStream =
178                                            new UnsyncByteArrayOutputStream();
179                                    ObjectOutputStream objectOutputStream = new ObjectOutputStream(
180                                            newJobDataOutputStream);
181    
182                                    objectOutputStream.writeObject(jobDataMap);
183    
184                                    objectOutputStream.close();
185    
186                                    jobData = newJobDataOutputStream.toByteArray();
187    
188                                    array[0] = jobName;
189                                    array[1] = jobGroup;
190                                    array[2] = jobData;
191    
192                                    arrays.add(array);
193                            }
194    
195                            return arrays;
196                    }
197                    finally {
198                            DataAccess.cleanUp(con, ps, rs);
199                    }
200            }
201    
202            protected void updateJobDetail(
203                            String jobName, String jobGroup, byte[] jobData)
204                    throws Exception {
205    
206                    Connection con = null;
207                    PreparedStatement ps = null;
208                    ResultSet rs = null;
209    
210                    try {
211                            con = DataAccess.getConnection();
212    
213                            ps = con.prepareStatement(
214                                    "update QUARTZ_JOB_DETAILS set JOB_DATA = ? where JOB_NAME = " +
215                                            "? and JOB_GROUP = ?");
216    
217                            ps.setBytes(1, jobData);
218                            ps.setString(2, jobName);
219                            ps.setString(3, jobGroup);
220    
221                            ps.executeUpdate();
222                    }
223                    finally {
224                            DataAccess.cleanUp(con, ps, rs);
225                    }
226            }
227    
228    }