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