001/*
002 * This library is part of OpenCms -
003 * the Open Source Content Management System
004 *
005 * Copyright (c) Alkacon Software GmbH & Co. KG (http://www.alkacon.com)
006 *
007 * This library is free software; you can redistribute it and/or
008 * modify it under the terms of the GNU Lesser General Public
009 * License as published by the Free Software Foundation; either
010 * version 2.1 of the License, or (at your option) any later version.
011 *
012 * This library is distributed in the hope that it will be useful,
013 * but WITHOUT ANY WARRANTY; without even the implied warranty of
014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
015 * Lesser General Public License for more details.
016 *
017 * For further information about Alkacon Software GmbH & Co. KG, please see the
018 * company website: http://www.alkacon.com
019 *
020 * For further information about OpenCms, please see the
021 * project website: http://www.opencms.org
022 *
023 * You should have received a copy of the GNU Lesser General Public
024 * License along with this library; if not, write to the Free Software
025 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
026 */
027
028package org.opencms.publish;
029
030import org.opencms.db.CmsDbContext;
031import org.opencms.db.CmsDriverManager;
032import org.opencms.main.CmsException;
033import org.opencms.main.CmsLog;
034import org.opencms.main.OpenCms;
035import org.opencms.monitor.CmsMemoryMonitor;
036
037import java.util.ArrayList;
038import java.util.Collections;
039import java.util.Iterator;
040import java.util.List;
041
042import org.apache.commons.collections.Buffer;
043import org.apache.commons.collections.BufferUtils;
044import org.apache.commons.collections.buffer.CircularFifoBuffer;
045import org.apache.commons.collections.buffer.TypedBuffer;
046import org.apache.commons.logging.Log;
047
048/**
049 * List of already finished publish jobs.<p>
050 *
051 * @since 6.5.5
052 */
053public class CmsPublishHistory {
054
055    /** The log object for this class. */
056    protected static final Log LOG = CmsLog.getLog(CmsPublishHistory.class);
057
058    /** The publish engine. */
059    protected final CmsPublishEngine m_publishEngine;
060
061    /**
062     * Default constructor.<p>
063     *
064     * @param publishEngine the publish engine instance
065     */
066    protected CmsPublishHistory(final CmsPublishEngine publishEngine) {
067
068        m_publishEngine = publishEngine;
069    }
070
071    /**
072     * Returns (and initializes) the queue.<p>
073     *
074     * @param size the history size
075     *
076     * @return the queue buffer
077     */
078    public static Buffer getQueue(int size) {
079
080        if (CmsLog.INIT.isInfoEnabled()) {
081            CmsLog.INIT.info(
082                Messages.get().getBundle().key(Messages.INIT_PUBLISH_HISTORY_SIZE_SET_1, new Integer(size)));
083        }
084
085        return BufferUtils.synchronizedBuffer(TypedBuffer.decorate(new CircularFifoBuffer(size) {
086
087            /** The serialization version id constant. */
088            private static final long serialVersionUID = -6257542123241183114L;
089
090            /**
091             * Called when the queue is full to remove the oldest element.<p>
092             *
093             * @see org.apache.commons.collections.buffer.BoundedFifoBuffer#remove()
094             */
095            @Override
096            public Object remove() {
097
098                CmsPublishJobInfoBean publishJob = (CmsPublishJobInfoBean)super.remove();
099                try {
100                    OpenCms.getPublishManager().getEngine().getPublishHistory().remove(publishJob);
101                } catch (CmsException exc) {
102                    if (LOG.isErrorEnabled()) {
103                        LOG.error(exc.getLocalizedMessage(), exc);
104                    }
105                }
106                return publishJob;
107            }
108        }, CmsPublishJobInfoBean.class));
109    }
110
111    /**
112     * Adds the given publish job to the list.<p>
113     *
114     * @param publishJob the publish job object to add
115     *
116     * @throws CmsException if something goes wrong
117     */
118    protected void add(CmsPublishJobInfoBean publishJob) throws CmsException {
119
120        OpenCms.getMemoryMonitor().cachePublishJobInHistory(publishJob);
121        // write job to db if necessary
122        if (OpenCms.getMemoryMonitor().requiresPersistency()) {
123            CmsDbContext dbc = m_publishEngine.getDbContext(null);
124            try {
125                m_publishEngine.getDriverManager().writePublishJob(dbc, publishJob);
126                // additionally, write the publish report
127                m_publishEngine.getDriverManager().writePublishReport(dbc, publishJob);
128                // delete publish list of started job
129                m_publishEngine.getDriverManager().deletePublishList(dbc, publishJob.getPublishHistoryId());
130            } catch (CmsException e) {
131                dbc.rollback();
132                LOG.error(e.getLocalizedMessage(), e);
133                throw e;
134            } finally {
135                dbc.clear();
136            }
137        }
138    }
139
140    /**
141     * Returns an unmodifiable list representation of this list.<p>
142     *
143     * @return a list of {@link CmsPublishJobFinished} objects
144     */
145    protected List<CmsPublishJobFinished> asList() {
146
147        List<CmsPublishJobInfoBean> cachedPublishJobs = OpenCms.getMemoryMonitor().getAllCachedPublishJobsInHistory();
148        List<CmsPublishJobFinished> result = new ArrayList<CmsPublishJobFinished>(cachedPublishJobs.size());
149        Iterator<CmsPublishJobInfoBean> it = cachedPublishJobs.iterator();
150        while (it.hasNext()) {
151            CmsPublishJobInfoBean publishJob = it.next();
152            result.add(new CmsPublishJobFinished(publishJob));
153        }
154        return Collections.unmodifiableList(result);
155    }
156
157    /**
158     * Initializes the internal FIFO queue with publish jobs from the database.<p>
159     */
160    protected void initialize() {
161
162        CmsDriverManager driverManager = m_publishEngine.getDriverManager();
163        CmsDbContext dbc = m_publishEngine.getDbContext(null);
164
165        try {
166            OpenCms.getMemoryMonitor().flushCache(CmsMemoryMonitor.CacheType.PUBLISH_HISTORY);
167            // read all finished published jobs from the database
168            List<CmsPublishJobInfoBean> publishJobs = driverManager.readPublishJobs(dbc, 1L, Long.MAX_VALUE);
169            for (Iterator<CmsPublishJobInfoBean> i = publishJobs.iterator(); i.hasNext();) {
170                CmsPublishJobInfoBean job = i.next();
171                OpenCms.getMemoryMonitor().cachePublishJobInHistory(job);
172            }
173        } catch (CmsException exc) {
174            dbc.rollback();
175            if (LOG.isErrorEnabled()) {
176                LOG.error(exc.getLocalizedMessage(), exc);
177            }
178        } finally {
179            dbc.clear();
180        }
181    }
182
183    /**
184     * Removes the given job from the list.<p>
185     *
186     * @param publishJob the publish job to remove
187     *
188     * @throws CmsException if something goes wrong
189     */
190    protected void remove(CmsPublishJobInfoBean publishJob) throws CmsException {
191
192        OpenCms.getMemoryMonitor().uncachePublishJobInHistory(publishJob);
193        // delete job from db if necessary
194        if (OpenCms.getMemoryMonitor().requiresPersistency()) {
195            CmsDbContext dbc = m_publishEngine.getDbContext(null);
196            try {
197                OpenCms.getPublishManager().getEngine().getDriverManager().deletePublishJob(
198                    dbc,
199                    publishJob.getPublishHistoryId());
200            } catch (CmsException e) {
201                dbc.rollback();
202                LOG.error(e.getLocalizedMessage(), e);
203                throw e;
204            } finally {
205                dbc.clear();
206            }
207        }
208
209        m_publishEngine.publishJobRemoved(publishJob);
210    }
211}