/* * Copyright (C) 20016 eXo Platform. * * This is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation; either version 2.1 of * the License, or (at your option) any later version. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this software; if not, write to the Free * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA * 02110-1301 USA, or see the FSF site: http://www.fsf.org. */ package org.exoplatform.services.cms.documents; import org.exoplatform.services.log.ExoLogger; import org.exoplatform.services.log.Log; import javax.jcr.Node; import javax.jcr.version.Version; import javax.jcr.version.VersionHistory; import javax.jcr.version.VersionIterator; import java.util.ArrayList; import java.util.Collections; import java.util.Date; import java.util.HashMap; import java.util.List; import java.util.Map; public class VersionHistoryUtils { protected static final Log log = ExoLogger.getLogger(VersionHistoryUtils.class); private static final int DOCUMENT_AUTO_DEFAULT_VERSION_MAX = 0; private static final int DOCUMENT_AUTO_DEFAULT_VERSION_EXPIRED = 0; public static final String NT_FILE = "nt:file"; public static final String MIX_VERSIONABLE = "mix:versionable"; private static String maxAllowVersionProp = "jcr.documents.versions.max"; private static String expirationTimeProp = "jcr.documents.versions.expiration"; private static int maxAllowVersion; private static long maxLiveTime; static { try { maxAllowVersion = Integer.parseInt(System.getProperty(maxAllowVersionProp)); maxLiveTime = Integer.parseInt(System.getProperty(expirationTimeProp)); //ignore invalid input config if(maxAllowVersion < 0) maxAllowVersion = DOCUMENT_AUTO_DEFAULT_VERSION_MAX; if(maxLiveTime < 0) maxLiveTime = DOCUMENT_AUTO_DEFAULT_VERSION_EXPIRED; }catch(NumberFormatException nex){ maxAllowVersion = DOCUMENT_AUTO_DEFAULT_VERSION_MAX; maxLiveTime = DOCUMENT_AUTO_DEFAULT_VERSION_EXPIRED; } maxLiveTime = maxLiveTime * 24 * 60 * 60 * 1000; } /** * Create new version and clear redundant versions * * @param nodeVersioning */ public static Version createVersion(Node nodeVersioning) throws Exception { if(!nodeVersioning.isNodeType(NT_FILE)) { if(log.isDebugEnabled()){ log.debug("Version history is not impact with non-nt:file documents, there'is not any version created."); } return null; } if(!nodeVersioning.isNodeType(MIX_VERSIONABLE)){ if(nodeVersioning.canAddMixin(MIX_VERSIONABLE)) { nodeVersioning.addMixin(MIX_VERSIONABLE); nodeVersioning.save(); } return null; } Version version = null; if (!nodeVersioning.isCheckedOut()) { nodeVersioning.checkout(); } else { version = nodeVersioning.checkin(); nodeVersioning.checkout(); } if(maxAllowVersion!= DOCUMENT_AUTO_DEFAULT_VERSION_MAX || maxLiveTime != DOCUMENT_AUTO_DEFAULT_VERSION_EXPIRED) { removeRedundant(nodeVersioning); } nodeVersioning.save(); return version; } /** * Remove redundant version * - Remove versions has been expired * - Remove versions over max allow * @param nodeVersioning * @throws Exception */ private static void removeRedundant(Node nodeVersioning) throws Exception{ VersionHistory versionHistory = nodeVersioning.getVersionHistory(); String baseVersion = nodeVersioning.getBaseVersion().getName(); String rootVersion = nodeVersioning.getVersionHistory().getRootVersion().getName(); VersionIterator versions = versionHistory.getAllVersions(); Date currentDate = new Date(); Map<String, String> lstVersions = new HashMap<String, String>(); List<String> lstVersionTime = new ArrayList<String>(); while (versions.hasNext()) { Version version = versions.nextVersion(); if(rootVersion.equals(version.getName()) || baseVersion.equals(version.getName())) continue; if (maxLiveTime!= DOCUMENT_AUTO_DEFAULT_VERSION_EXPIRED && currentDate.getTime() - version.getCreated().getTime().getTime() > maxLiveTime) { versionHistory.removeVersion(version.getName()); } else { lstVersions.put(String.valueOf(version.getCreated().getTimeInMillis()), version.getName()); lstVersionTime.add(String.valueOf(version.getCreated().getTimeInMillis())); } } if (maxAllowVersion <= lstVersionTime.size() && maxAllowVersion!= DOCUMENT_AUTO_DEFAULT_VERSION_MAX) { Collections.sort(lstVersionTime); String[] lsts = lstVersionTime.toArray(new String[lstVersionTime.size()]); for (int j = 0; j <= lsts.length - maxAllowVersion; j++) { versionHistory.removeVersion(lstVersions.get(lsts[j])); } } } }