/*
 * Copyright 2009 Wyona
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *      http://www.wyona.org/licenses/APACHE-LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 */

package org.wyona.yanel.core.util;

import org.wyona.yanel.core.Resource;
import org.wyona.yanel.core.api.attributes.ModifiableV2;
import org.wyona.yanel.core.api.attributes.VersionableV2;
import org.wyona.yanel.core.api.attributes.WorkflowableV1;
import org.wyona.yanel.core.attributes.versionable.RevisionInformation;

import org.apache.log4j.Logger;

/**
 * Utility class in order to roll-back to a particular revision
 */
public class VersioningUtil {

    private static Logger log = Logger.getLogger(VersioningUtil.class);

    /**
     * @param resource Resource which shall be rolled back
     * @param revisionName Revision name to which shall be rolled back
     * @param userName User who is executing the roll back
     */
    public static void rollBack(Resource resource, String revisionName, String userName) {
        if (ResourceAttributeHelper.hasAttributeImplemented(resource, "Versionable", "2")) {
            try {
                VersionableV2 versionableRes = (VersionableV2) resource;
                if (!versionableRes.isCheckedOut()) {
                    versionableRes.checkout(userName);
                    versionableRes.restore(revisionName);
                    versionableRes.checkin("Rolled back to revision '" + revisionName + "'");
                    if (ResourceAttributeHelper.hasAttributeImplemented(resource, "Workflowable", "1")) {
                        WorkflowableV1 workflowableRes = (WorkflowableV1) resource;
                        // TBD: Should the workflow state of the old revision be used (as is) or rather workflow.getInitialState()
                        //log.debug("Revision head: " + getRevisionHead(versionableRes));
                        workflowableRes.setWorkflowState(workflowableRes.getWorkflowState(revisionName), getRevisionHead(versionableRes));
                    } else {
                        log.info("Cannot set workflow, because resource '" + resource.getPath() + "' is not WorkflowableV1");
                    }
                } else {
                    log.warn("Resource is already checked out by user '" + versionableRes.getCheckoutUserID() + "' and hence cannot be rolled back at the moment!");
                }
            } catch(Exception e) {
                log.error(e, e);
            }
        } else {
            log.warn("Cannot be rolled back, because resource '" + resource.getPath() + "' is not VersionableV2");
        }
    }

    /**
     * Get revision number/name of head (most recent) revision (WARN: Peformance/Scalability)
     */
    private static String getRevisionHead(VersionableV2 resource) throws Exception {
        RevisionInformation[] ri = resource.getRevisions();
        java.util.Arrays.sort(ri);
        return ri[0].getName();
    }
}

@@ -779,32 +779,90 @@
 .VersionableV2;%0A
+import org.wyona.yanel.core.api.attributes.VersionableV3;%0A
 import org.wyona
@@ -1190,24 +1190,61 @@
 );%0A%0A    /**%0A
+     * Revert to a previous revision%0A
      * @para
@@ -1317,17 +1317,26 @@
 ionName 
-R
+Previous r
 evision 
@@ -1997,205 +1997,834 @@
     
-if (ResourceAttributeHelper.hasAttributeImplemented(resource, %22Workflowable%22, %221%22)) %7B%0A                        WorkflowableV1 workflowableRes = (WorkflowableV1) resource;%0A                        // 
+//RevisionInformation newRevInfo = versionableRes.checkin(%22Rolled back to revision '%22 + revisionName + %22'%22); // INFO: Maybe part of VersionableV3?! %0A                    if (ResourceAttributeHelper.hasAttributeImplemented(resource, %22Workflowable%22, %221%22)) %7B%0A                        String newRevisionName = null;%0A                        if (ResourceAttributeHelper.hasAttributeImplemented(resource, %22Versionable%22, %223%22)) %7B%0A                            newRevisionName = getMostRecentRevision((VersionableV3) resource).getName();%0A                        %7D%0A                        if (newRevisionName != null) %7B%0A                            WorkflowableV1 workflowableRes = (WorkflowableV1) resource;%0A                            if (workflowableRes.getWorkflowState(newRevisionName) == null) %7B%0A                                // TODO/
 TBD:
@@ -2947,18 +2947,52 @@
         
+       
+ 
 //
+if (log.isDebugEnabled()) 
 log.debu
@@ -3038,33 +3038,100 @@
 ersionableRes));
-%0A
+ // WARN: Very bad peformance, because does not scale well!%0A        
                 
@@ -3253,16 +3253,481 @@
 eRes));%0A
+                            %7D else %7B%0A                                log.warn(%22The workflow state has already been set (probably by the checkin method): %22 + workflowableRes.getWorkflowState(newRevisionName));%0A                            %7D%0A                        %7D else %7B%0A                            log.warn(%22Cannot determine the revision name, hence please make sure to set the workflow state inside the checkin method if applicable!%22);%0A                        %7D%0A
         
@@ -4661,11 +4661,517 @@
 );%0A    %7D
+%0A%0A    /**%0A     * Get most recent revision%0A     * @param resource Resource which implements versionable V3%0A     */%0A    private static RevisionInformation getMostRecentRevision(VersionableV3 resource) throws Exception %7B%0A        java.util.Iterator it = resource.getRevisions(false);%0A        if (it.hasNext()) %7B%0A            return (RevisionInformation)it.next();%0A        %7D else %7B%0A            throw new Exception(%22Resource '%22 + ((Resource)resource).getPath() + %22' has no most recent revision!%22);%0A        %7D%0A    %7D
 %0A%7D%0A

check first on the workflow state