ExtendedParserTransformer.java :  » Web-Framework » cocoon » org » apache » cocoon » transformation » Java Open Source

Java Open Source » Web Framework » cocoon 
cocoon » org » apache » cocoon » transformation » ExtendedParserTransformer.java
/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You 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.cocoon.transformation;

import net.sourceforge.chaperon.model.extended.ExtendedGrammar;
import net.sourceforge.chaperon.process.extended.ExtendedDirectParserProcessor;

import org.apache.avalon.excalibur.pool.Recyclable;
import org.apache.avalon.framework.activity.Disposable;
import org.apache.avalon.framework.logger.LogEnabled;
import org.apache.avalon.framework.logger.Logger;
import org.apache.avalon.framework.parameters.ParameterException;
import org.apache.avalon.framework.parameters.Parameterizable;
import org.apache.avalon.framework.parameters.Parameters;
import org.apache.avalon.framework.service.ServiceException;
import org.apache.avalon.framework.service.ServiceManager;
import org.apache.avalon.framework.service.Serviceable;

import org.apache.cocoon.ProcessingException;
import org.apache.cocoon.caching.CacheableProcessingComponent;
import org.apache.cocoon.components.source.SourceUtil;
import org.apache.cocoon.environment.SourceResolver;
import org.apache.cocoon.xml.XMLConsumer;

import org.apache.excalibur.source.Source;
import org.apache.excalibur.source.SourceException;
import org.apache.excalibur.source.SourceValidity;
import org.apache.excalibur.store.Store;

import org.exolab.castor.mapping.Mapping;
import org.exolab.castor.mapping.MappingException;
import org.exolab.castor.xml.UnmarshalHandler;
import org.exolab.castor.xml.Unmarshaller;

import org.xml.sax.InputSource;
import org.xml.sax.SAXException;

import java.io.IOException;
import java.io.Serializable;

import java.util.Map;

/**
 * @author <a href="mailto:stephan@apache.org">Stephan Michels </a>
 * @version CVS $Id: ExtendedParserTransformer.java 433543 2006-08-22 06:22:54Z crossley $
 */
public class ExtendedParserTransformer extends ExtendedDirectParserProcessor
        implements Transformer, LogEnabled, Serviceable, Parameterizable,
                   Recyclable, Disposable, CacheableProcessingComponent
{
  private String grammar = null;
  private Source grammarSource = null;
  private Logger logger = null;
  private ServiceManager manager = null;
  private SourceResolver resolver = null;

  /**
   * Provide component with a logger.
   *
   * @param logger the logger
   */
  public void enableLogging(Logger logger)
  {
    this.logger = logger;

    // TODO: check if the loglevel is correct LogKitLogger -> Logger
    //setLog(new AvalonLogger(logger));
  }

  /**
   * Pass the ServiceManager to the object. The Serviceable implementation
   * should use the specified ServiceManager to acquire the services it needs
   * for execution.
   *
   * @param manager The ServiceManager which this Serviceable uses.
   */
  public void service(ServiceManager manager)
  {
    this.manager = manager;
  }

  /**
   * Provide component with parameters.
   *
   * @param parameters the parameters
   *
   * @throws ParameterException if parameters are invalid
   */
  public void parameterize(Parameters parameters) throws ParameterException
  {
    //setRecovery(parameters.getParameterAsBoolean("recovery", false));
  }

  /**
   * Set the <code>XMLConsumer</code> that will receive XML data.
   *
   * @param consumer
   */
  public void setConsumer(XMLConsumer consumer)
  {
    setContentHandler(consumer);
    setLexicalHandler(consumer);
  }

  /**
   * Set the SourceResolver, objectModel Map, the source and sitemap Parameters used to process the
   * request.
   *
   * @param resolver Source resolver
   * @param objectmodel Object model
   * @param src Source
   * @param parameters Parameters
   *
   * @throws IOException
   * @throws ProcessingException
   * @throws SAXException
   */
  public void setup(SourceResolver resolver, Map objectmodel, String src, Parameters parameters)
    throws ProcessingException, SAXException, IOException
  {
    this.resolver = resolver;

    Store store = null;

    try
    {
      this.grammar = src;

      this.grammarSource = resolver.resolveURI(this.grammar);

      // Retrieve the parser automaton from the transient store
      store = (Store)this.manager.lookup(Store.TRANSIENT_STORE);

      GrammarEntry entry = (GrammarEntry)store.get(this.grammarSource.getURI());

      // If the parser automaton has changed, rebuild the parser automaton
      if ((entry==null) || (entry.getValidity()==null) ||
          ((entry.getValidity().isValid(this.grammarSource.getValidity()))<=0))
      {
        this.logger.info("(Re)building the grammar from '"+this.grammarSource.getURI()+"'");

        if (this.grammarSource.getInputStream()==null)
          throw new ProcessingException("Source '"+this.grammarSource.getURI()+"' not found");

        Mapping mapping = new Mapping();

        mapping.loadMapping(new InputSource(ExtendedGrammar.class.getResource("mapping.xml")
                                                                 .openStream()));

        Unmarshaller unmarshaller = new Unmarshaller(ExtendedGrammar.class);
        unmarshaller.setMapping(mapping);

        UnmarshalHandler unmarshalHandler = unmarshaller.createHandler();
        SourceUtil.toSAX(this.manager, this.grammarSource, null,
                         Unmarshaller.getContentHandler(unmarshalHandler));

        ExtendedGrammar grammar = (ExtendedGrammar)unmarshalHandler.getObject();

        if (grammar==null)
          throw new ProcessingException("Error while reading the grammar from "+src);

        setExtendedGrammar(grammar);

        this.logger.info("Store grammar into store for '"+this.grammarSource.getURI()+"'");
        store.store(this.grammarSource.getURI(),
                    new GrammarEntry(grammar, this.grammarSource.getValidity()));
      }
      else
      {
        this.logger.info("Getting grammar from store for '"+this.grammarSource.getURI()+"'");
        setExtendedGrammar(entry.getExtendedGrammar());
      }
    }
    catch (MappingException me)
    {
      throw new ProcessingException("Error while reading the grammar", me);
    }
    catch (SourceException se)
    {
      throw new ProcessingException("Error during resolving of '"+src+"'.", se);
    }
    catch (ServiceException se)
    {
      throw new ProcessingException("Could not lookup for service", se);
    }
    finally
    {
      if (store!=null)
        this.manager.release(store);
    }
  }

  /**
   * Generate the unique key. This key must be unique inside the space of this component.
   *
   * @return The generated key hashes the src
   */
  public Serializable getKey()
  {
    return this.grammarSource.getURI();
  }

  /**
   * Generate the validity object.
   *
   * @return The generated validity object or <code>null</code> if the component is currently not
   *         cacheable.
   */
  public SourceValidity getValidity()
  {
    return this.grammarSource.getValidity();
  }

  /**
   * Recycle this component. All instance variables are set to <code>null</code>.
   */
  public void recycle()
  {
    if ((this.resolver!=null) && (this.grammarSource!=null))
    {
      this.resolver.release(this.grammarSource);
      this.grammarSource = null;
    }
  }

  /**
   * The dispose operation is called at the end of a components lifecycle.
   */
  public void dispose()
  {
    if ((this.resolver!=null) && (this.grammarSource!=null))
    {
      this.resolver.release(this.grammarSource);
      this.grammarSource = null;
    }

    this.manager = null;
  }

  /**
   * This class represent a entry in a store to cache the parser automaton.
   */
  public static class GrammarEntry implements Serializable {
    private SourceValidity validity = null;
    private ExtendedGrammar grammar = null;

    /**
     * Create a new entry.
     *
     * @param grammar Extended grammar
     * @param validity Validity for the grammar file.
     */
    public GrammarEntry(ExtendedGrammar grammar, SourceValidity validity)
    {
      this.grammar = grammar;
      this.validity = validity;
    }

    /**
     * Return the validity of the grammar file.
     *
     * @return Validity of the grammar file.
     */
    public SourceValidity getValidity()
    {
      return this.validity;
    }

    /**
     * Return the parser automaton.
     *
     * @return Parser automaton.
     */
    public ExtendedGrammar getExtendedGrammar()
    {
      return this.grammar;
    }

    private void writeObject(java.io.ObjectOutputStream out)
      throws IOException
    {
      out.writeObject(validity);
      out.writeObject(grammar);
    }

    private void readObject(java.io.ObjectInputStream in)
      throws IOException, ClassNotFoundException
    {
      validity = (SourceValidity)in.readObject();
      grammar = (ExtendedGrammar)in.readObject();
    }
  }
}
java2s.com  | Contact Us | Privacy Policy
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.