content: /*
   * VisitorStrategy.java January 2010
   *
   * Copyright (C) 2010, Niall Gallagher <niallg@users.sf.net>
   *
   * 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 com.aliyun.odps.simpleframework.xml.strategy;
  
  import com.aliyun.odps.simpleframework.xml.stream.NodeMap;
  import com.aliyun.odps.simpleframework.xml.stream.OutputNode;
  import java.util.Map;
  
  import com.aliyun.odps.simpleframework.xml.stream.InputNode;
  
  /**
   * The <code>VisitorStrategy</code> object is a simplification of a
   * strategy, which allows manipulation of the serialization process.
   * Typically implementing a <code>Strategy</code> is impractical as
   * it requires the implementation to determine the type a node
   * represents. Instead it is often easier to visit each node that
   * is being serialized or deserialized and manipulate it so that 
   * the resulting XML can be customized. 
   * <p>
   * To perform customization in this way a <code>Visitor</code> can
   * be implemented. This can be passed to this strategy which will 
   * ensure the visitor is given each XML element as it is either 
   * being serialized or deserialized. Such an inversion of control
   * allows the nodes to be manipulated with little effort. By 
   * default this used <code>TreeStrategy</code> object as a default
   * strategy to delegate to. However, any strategy can be used.
   * 
   * @author Niall Gallagher
   * 
   * @see Visitor
   */
  public class VisitorStrategy implements Strategy {
     
     /**
      * This is the strategy that is delegated to by this strategy.
      */
     private final Strategy strategy;
     
     /**
      * This is the visitor that is used to intercept serialization.
      */
     private final Visitor visitor;
     
     /**
      * Constructor for the <code>VisitorStrategy</code> object. This
      * strategy requires a visitor implementation that can be used
      * to intercept the serialization and deserialization process.
      * 
      * @param visitor this is the visitor used for interception
      */
     public VisitorStrategy(Visitor visitor) {
        this(visitor, new TreeStrategy());
     }
     
     /**
      * Constructor for the <code>VisitorStrategy</code> object. This
      * strategy requires a visitor implementation that can be used
      * to intercept the serialization and deserialization process.
      * 
      * @param visitor this is the visitor used for interception
      * @param strategy this is the strategy to be delegated to
      */
     public VisitorStrategy(Visitor visitor, Strategy strategy) {
        this.strategy = strategy;
        this.visitor = visitor;
     }
  
     /**
      * This method will read with  an internal strategy after it has
      * been intercepted by the visitor. Interception of the XML node
      * before it is delegated to the internal strategy allows the 
      * visitor to change some attributes or details before the node
      * is interpreted by the strategy.
      * 
      * @param type this is the type of the root element expected
      * @param node this is the node map used to resolve an override
      * @param map this is used to maintain contextual information
      * 
      * @return the value that should be used to describe the instance
      */
     public Value read(Type type, NodeMap<InputNode> node, Map map) throws Exception {
        if(visitor != null) {
           visitor.read(type, node);
        }
        return strategy.read(type, node, map);
     }
  
     /**
      * This method will write with an internal strategy before it has
      * been intercepted by the visitor. Interception of the XML node
      * before it is delegated to the internal strategy allows the 
      * visitor to change some attributes or details before the node
      * is interpreted by the strategy.
      * 
      * @param type this is the type of the root element expected
      * @param node this is the node map used to resolve an override
      * @param map this is used to maintain contextual information
      * 
      * @return the value that should be used to describe the instance
      */
     public boolean write(Type type, Object value, NodeMap<OutputNode> node, Map map) throws Exception {
        boolean result = strategy.write(type, value, node, map); 
        
        if(visitor != null) {
           visitor.write(type, node);
        }
        return result;
     }
  }