/*
 * $Header: /home/cvspublic/jakarta-slide/src/share/org/apache/slide/macro/MacroPropertyUpdater.java,v 1.9 2005/03/11 16:30:29 luetzkendorf Exp $
 * $Revision: 1.9 $
 * $Date: 2005/03/11 16:30:29 $
 *
 * ====================================================================
 *
 * Copyright 1999-2002 The Apache Software Foundation 
 *
 * 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.apache.org/licenses/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.apache.slide.macro;

import org.apache.slide.common.Domain;
import org.apache.slide.common.HelperProvider;
import org.apache.slide.content.Content;
import org.apache.slide.content.NodeRevisionDescriptor;
import org.apache.slide.content.NodeRevisionDescriptors;
import org.apache.slide.event.MacroEvent;
import org.apache.slide.event.MacroListener;
import org.apache.slide.event.VetoException;
import org.apache.slide.structure.SubjectNode;
import org.apache.slide.util.conf.Configurable;
import org.apache.slide.util.conf.Configuration;
import org.apache.slide.util.conf.ConfigurationException;

/**
 * Event handler (listener) that updates some DAV: properties
 * on COPY or MOVE actions.
 * 
 * <p>The DAV: properties currently updated are: displayname and owner.
 * 
 */
public class MacroPropertyUpdater 
   implements MacroListener, Configurable
{
   private boolean updateDisplayName = true;
   private boolean updateOwnerOnMove = false;
   private boolean updateOwnerOnCopy = true;
   
   /* 
    * @see org.apache.slide.util.conf.Configurable#configure(org.apache.slide.util.conf.Configuration)
    */
   public void configure(Configuration configuration)
         throws ConfigurationException
   {
     
     try {
        this.updateDisplayName = configuration.getConfiguration("update-displayname")
           .getValueAsBoolean(this.updateDisplayName);
     } catch (Exception e) {
        // ignore, maintain default 
     } 
     
     try {
        this.updateOwnerOnMove = configuration.getConfiguration("update-owner-on-move")
           .getValueAsBoolean(this.updateOwnerOnMove);
     } catch (Exception e) {
        // ignore, maintain default 
     } 

     try {
        this.updateOwnerOnCopy = configuration.getConfiguration("update-owner-on-copy")
           .getValueAsBoolean(this.updateOwnerOnCopy);
     } catch (Exception e) {
        // ignore, maintain default 
     }
   }
   
   /* 
    * @see org.apache.slide.event.MacroListener#copy(org.apache.slide.event.MacroEvent)
    */
   public void copy(MacroEvent event) throws VetoException
   {
      try {
         Content helper = ((HelperProvider)event.getSource()).getContentHelper();
         
         NodeRevisionDescriptors destNrds = helper.retrieve(event.getToken(), 
                                                            event.getTargetURI());
         NodeRevisionDescriptor destNrd = helper.retrieve(event.getToken(), 
                                                          destNrds);
         
         boolean anyThingUpdated = false;
         
         // update display name (if changed)
         if (this.updateDisplayName) {
            String displayName = getFilename(event.getTargetURI());
            if (!displayName.equals(destNrd.getName())) {
               destNrd.setName(displayName);
               anyThingUpdated = true;
            }
         }

         // update owner (if changed)
         if (this.updateOwnerOnCopy) {
            String newOwner = event.getToken().getCredentialsToken().getPublicCredentials();
            if (newOwner == null || newOwner.equals("") || newOwner.equals("/")) {
                newOwner = SubjectNode.UNAUTHENTICATED_URI;
            }
            if (!destNrd.getOwner().equals(newOwner)) {
               destNrd.setOwner(newOwner);
               anyThingUpdated = true;
            }
         }

         if (anyThingUpdated) {
            helper.store(event.getToken(), event.getTargetURI(), destNrd, null);
         }
         
      } 
      catch (Exception e) {
         Domain.error("Exception while copy", e);
      }
      
   }

   /* 
    * @see org.apache.slide.event.MacroListener#move(org.apache.slide.event.MacroEvent)
    */
   public void move(MacroEvent event) throws VetoException
   {
      try {
         Content helper = ((HelperProvider)event.getSource()).getContentHelper();
         
         NodeRevisionDescriptors destNrds = helper.retrieve(event.getToken(), 
                                                            event.getTargetURI());
         NodeRevisionDescriptor destNrd = helper.retrieve(event.getToken(), 
                                                          destNrds);
         
         boolean anyThingUpdated = false;
         
         // update display name (if changed)
         if (this.updateDisplayName) {
            String displayName = getFilename(event.getTargetURI());
            if (!displayName.equals(destNrd.getName())) {
               destNrd.setName(displayName);
               anyThingUpdated = true;
            }
         }

         // update owner (if changed)
         if (this.updateOwnerOnMove) {
            String newOwner = event.getToken().getCredentialsToken().getPublicCredentials();
            if (newOwner == null || newOwner.equals("") || newOwner.equals("/")) {
                newOwner = SubjectNode.UNAUTHENTICATED_URI;
            }
            if (!destNrd.getOwner().equals(newOwner)) {
               anyThingUpdated = true;
               destNrd.setOwner(newOwner);
            }
         }

         if (anyThingUpdated) {
             helper.store(event.getToken(), event.getTargetURI(), destNrd, null);
         }
      } 
      catch (Exception e) {
         Domain.error("Exception while move", e);
      }
   }
   
   
   /* 
    * @see org.apache.slide.event.MacroListener#delete(org.apache.slide.event.MacroEvent)
    */
   public void delete(MacroEvent event) throws VetoException
   {
   }
   

   /**
    * Returns the last part of an URI that is normaly called the name of
    * the collection of file.
    * <p>I bet there is anywhere such a method but I havn't found it.
    * @param uri
    * @return the name of the resource given by uri
    */
  private static String getFilename(String uri) {
      if (uri.indexOf('/') == -1) {
         return uri;
      }
      if (uri.equals("/")) {
         return "";
      }
      if (uri.endsWith("/")) {
         return uri.substring(1+uri.lastIndexOf('/', uri.length() - 2), 
                              uri.length() - 1);
      } else {
         return uri.substring(1+uri.lastIndexOf('/'));
      }
  }

//  private Content getContentHelper(MacroEvent event) {
//     Security security = NamespaceConfigUtil.getSecurityImplementation(
//             event.getNamespace());
//     Lock lock = NamespaceConfigUtil.getLockImplementation(
//             event.getNamespace(),
//             security);
//     Structure structure = NamespaceConfigUtil.getStructureImplementation(
//             event.getNamespace(),
//             security,
//             lock);     
//     Content helper = NamespaceConfigUtil.getContentImplementation(
//             event.getNamespace(),
//             security,
//             structure,
//             lock);
//     return helper;
//  }
}
