You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@struts.apache.org by mr...@apache.org on 2005/11/27 08:10:27 UTC

svn commit: r349187 [6/6] - in /struts/flow/trunk: ./ src/examples/WEB-INF/ src/examples/WEB-INF/guess/ src/examples/WEB-INF/portlet/ src/examples/WEB-INF/remote/ src/examples/remote/ src/java/ src/java/org/apache/struts/flow/ src/java/org/apache/strut...

Added: struts/flow/trunk/src/java/org/apache/struts/flow/core/source/impl/FileSource.java
URL: http://svn.apache.org/viewcvs/struts/flow/trunk/src/java/org/apache/struts/flow/core/source/impl/FileSource.java?rev=349187&view=auto
==============================================================================
--- struts/flow/trunk/src/java/org/apache/struts/flow/core/source/impl/FileSource.java (added)
+++ struts/flow/trunk/src/java/org/apache/struts/flow/core/source/impl/FileSource.java Sat Nov 26 23:10:08 2005
@@ -0,0 +1,546 @@
+/* 
+ * Copyright 2002-2004 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.struts.flow.core.source.impl;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.net.MalformedURLException;
+import java.net.URLConnection;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.ConcurrentModificationException;
+
+import org.apache.struts.flow.core.source.ModifiableSource;
+import org.apache.struts.flow.core.source.ModifiableTraversableSource;
+import org.apache.struts.flow.core.source.MoveableSource;
+import org.apache.struts.flow.core.source.Source;
+import org.apache.struts.flow.core.source.SourceException;
+import org.apache.struts.flow.core.source.SourceNotFoundException;
+import org.apache.struts.flow.core.source.SourceUtil;
+import org.apache.struts.flow.core.source.SourceValidity;
+import org.apache.struts.flow.core.source.impl.validity.FileTimeStampValidity;
+
+/**
+ * A {@link ModifiableTraversableSource} for filesystem objects.
+ *
+ * @author <a href="mailto:dev@avalon.apache.org">Avalon Development Team</a>
+ * @version $Id: FileSource.java,v 1.5 2004/02/28 11:47:24 cziegeler Exp $
+ */
+
+public class FileSource implements ModifiableTraversableSource, MoveableSource
+{
+
+    /** The file */
+    private File m_file;
+
+    /** The scheme */
+    private String m_scheme;
+
+    /** The URI of this source */
+    private String m_uri;
+
+    /**
+     * Builds a FileSource given an URI, which doesn't necessarily have to start with "file:"
+     * @param uri
+     * @throws SourceException
+     * @throws MalformedURLException
+     */
+    public FileSource(String uri) throws SourceException, MalformedURLException
+    {
+        int pos = SourceUtil.indexOfSchemeColon(uri);
+        if (pos == -1)
+        {
+            throw new MalformedURLException("Invalid URI : " + uri);
+        }
+
+        String scheme = uri.substring(0, pos);
+        String fileName = uri.substring(pos + 1);
+        fileName = SourceUtil.decodePath(fileName);
+        init(scheme, new File(fileName));
+    }
+
+    /**
+     * Builds a FileSource, given an URI scheme and a File.
+     * 
+     * @param scheme
+     * @param file
+     * @throws SourceException
+     */
+    public FileSource(String scheme, File file) throws SourceException
+    {
+        init(scheme, file);
+    }
+
+    private void init(String scheme, File file) throws SourceException
+    {
+        m_scheme = scheme;
+
+        String uri;
+        try
+        {
+            uri = file.toURL().toExternalForm();
+        }
+        catch (MalformedURLException mue)
+        {
+            // Can this really happen ?
+            throw new SourceException("Failed to get URL for file " + file, mue);
+        }
+
+        if (!uri.startsWith(scheme))
+        {
+            // Scheme is not "file:"
+            uri = scheme + ':' + uri.substring(uri.indexOf(':') + 1);
+        }
+
+        m_uri = uri;
+
+        m_file = file;
+    }
+
+    /**
+     * Get the associated file
+     */
+    public File getFile()
+    {
+        return m_file;
+    }
+
+    //----------------------------------------------------------------------------------
+    //  Source interface methods
+    //----------------------------------------------------------------------------------
+
+    /**
+     * @see org.apache.struts.flow.core.source.Source#getContentLength()
+     */
+    public long getContentLength()
+    {
+        return m_file.length();
+    }
+
+    /**
+     * @see org.apache.struts.flow.core.source.Source#getInputStream()
+     */
+    public InputStream getInputStream() throws IOException, SourceNotFoundException
+    {
+        try
+        {
+            return new FileInputStream(m_file);
+        }
+        catch (FileNotFoundException fnfe)
+        {
+            throw new SourceNotFoundException(m_uri + " doesn't exist.", fnfe);
+        }
+    }
+
+    /**
+     * @see org.apache.struts.flow.core.source.Source#getLastModified()
+     */
+    public long getLastModified()
+    {
+        return m_file.lastModified();
+    }
+
+    /**
+     * @see org.apache.struts.flow.core.source.Source#getMimeType()
+     */
+    public String getMimeType()
+    {
+        return URLConnection.getFileNameMap().getContentTypeFor(m_file.getName());
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.struts.flow.core.source.Source#getScheme()
+     */
+    public String getScheme()
+    {
+        return m_scheme;
+
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.struts.flow.core.source.Source#getURI()
+     */
+    public String getURI()
+    {
+        return m_uri;
+    }
+
+    /**
+     * Return a validity object based on the file's modification date.
+     * 
+     * @see org.apache.struts.flow.core.source.Source#getValidity()
+     */
+    public SourceValidity getValidity()
+    {
+        if (m_file.exists())
+        {
+            return new FileTimeStampValidity(m_file);
+        }
+        else
+        {
+            return null;
+        }
+    }
+
+    /**
+     * @see org.apache.struts.flow.core.source.Source#refresh()
+     */
+    public void refresh()
+    {
+        // Nothing to do...
+    }
+
+    /**
+     * Does this source actually exist ?
+     *
+     * @return true if the resource exists.
+     */
+    public boolean exists()
+    {
+        return getFile().exists();
+    }
+
+    //----------------------------------------------------------------------------------
+    //  TraversableSource interface methods
+    //----------------------------------------------------------------------------------
+
+    /**
+     * @see org.apache.struts.flow.core.source.TraversableSource#getChild(java.lang.String)
+     */
+    public Source getChild(String name) throws SourceException
+    {
+        if (!m_file.isDirectory())
+        {
+            throw new SourceException(getURI() + " is not a directory");
+        }
+
+        return new FileSource(this.getScheme(), new File(m_file, name));
+
+    }
+
+    /**
+     * @see org.apache.struts.flow.core.source.TraversableSource#getChildren()
+     */
+    public Collection getChildren() throws SourceException
+    {
+
+        if (!m_file.isDirectory())
+        {
+            throw new SourceException(getURI() + " is not a directory");
+        }
+
+        // Build a FileSource object for each of the children
+        File[] files = m_file.listFiles();
+
+        FileSource[] children = new FileSource[files.length];
+        for (int i = 0; i < files.length; i++)
+        {
+            children[i] = new FileSource(this.getScheme(), files[i]);
+        }
+
+        // Return it as a list
+        return Arrays.asList(children);
+    }
+
+    /**
+     * @see org.apache.struts.flow.core.source.TraversableSource#getName()
+     */
+    public String getName()
+    {
+        return m_file.getName();
+    }
+
+    /**
+     * @see org.apache.struts.flow.core.source.TraversableSource#getParent()
+     */
+    public Source getParent() throws SourceException
+    {
+        return new FileSource(getScheme(), m_file.getParentFile());
+    }
+
+    /**
+     * @see org.apache.struts.flow.core.source.TraversableSource#isCollection()
+     */
+    public boolean isCollection()
+    {
+        return m_file.isDirectory();
+    }
+
+    //----------------------------------------------------------------------------------
+    //  ModifiableSource interface methods
+    //----------------------------------------------------------------------------------
+
+    /**
+     * Get an <code>InputStream</code> where raw bytes can be written to.
+     * The signification of these bytes is implementation-dependent and
+     * is not restricted to a serialized XML document.
+     *
+     * The output stream returned actually writes to a temp file that replaces
+     * the real one on close. This temp file is used as lock to forbid multiple
+     * simultaneous writes. The real file is updated atomically when the output
+     * stream is closed.
+     *
+     * The returned stream must be closed or cancelled by the calling code.
+     *
+     * @return a stream to write to
+     * @throws ConcurrentModificationException if another thread is currently
+     *         writing to this file.
+     */
+    public OutputStream getOutputStream() throws IOException
+    {
+        // Create a temp file. It will replace the right one when writing terminates,
+        // and serve as a lock to prevent concurrent writes.
+        File tmpFile = new File(getFile().getPath() + ".tmp");
+
+        // Ensure the directory exists
+        tmpFile.getParentFile().mkdirs();
+
+        // Can we write the file ?
+        if (getFile().exists() && !getFile().canWrite())
+        {
+            throw new IOException("Cannot write to file " + getFile().getPath());
+        }
+
+        // Check if it temp file already exists, meaning someone else currently writing
+        if (!tmpFile.createNewFile())
+        {
+            throw new ConcurrentModificationException(
+                "File " + getFile().getPath() + " is already being written by another thread");
+        }
+
+        // Return a stream that will rename the temp file on close.
+        return new FileSourceOutputStream(tmpFile, this);
+    }
+
+    /**
+     * Can the data sent to an <code>OutputStream</code> returned by
+     * {@link #getOutputStream()} be cancelled ?
+     *
+     * @return true if the stream can be cancelled
+     */
+    public boolean canCancel(OutputStream stream)
+    {
+        if (stream instanceof FileSourceOutputStream)
+        {
+            FileSourceOutputStream fsos = (FileSourceOutputStream) stream;
+            if (fsos.getSource() == this)
+            {
+                return fsos.canCancel();
+            }
+        }
+
+        // Not a valid stream for this source
+        throw new IllegalArgumentException("The stream is not associated to this source");
+    }
+
+    /**
+     * Cancel the data sent to an <code>OutputStream</code> returned by
+     * {@link #getOutputStream()}.
+     * <p>
+     * After cancel, the stream should no more be used.
+     */
+    public void cancel(OutputStream stream) throws SourceException
+    {
+        if (stream instanceof FileSourceOutputStream)
+        {
+            FileSourceOutputStream fsos = (FileSourceOutputStream) stream;
+            if (fsos.getSource() == this)
+            {
+                try
+                {
+                    fsos.cancel();
+                }
+                catch (Exception e)
+                {
+                    throw new SourceException("Exception during cancel.", e);
+                }
+                return;
+            }
+        }
+
+        // Not a valid stream for this source
+        throw new IllegalArgumentException("The stream is not associated to this source");
+    }
+
+    /**
+     * Delete the source.
+     */
+    public void delete() throws SourceException
+    {
+        if (!m_file.exists())
+        {
+            throw new SourceNotFoundException("Cannot delete non-existing file " + m_file.toString());
+        }
+        
+        if (!m_file.delete())
+        {
+            throw new SourceException("Could not delete " + m_file.toString() + " (unknown reason)");
+        } 
+    }
+
+    //----------------------------------------------------------------------------------
+    //  ModifiableTraversableSource interface methods
+    //----------------------------------------------------------------------------------
+
+    /**
+     * @see org.apache.struts.flow.core.source.ModifiableTraversableSource#makeCollection()
+     */
+    public void makeCollection() throws SourceException
+    {
+        m_file.mkdirs();
+    }
+
+    //----------------------------------------------------------------------------------
+    //  MoveableSource interface methods
+    //----------------------------------------------------------------------------------
+
+    /**
+     * @see org.apache.struts.flow.core.source.MoveableSource#copyTo(org.apache.struts.flow.core.source.Source)
+     */
+    public void copyTo(Source destination) throws SourceException
+    {
+        try
+        {
+            SourceUtil.copy(this.getInputStream(), ((ModifiableSource) destination).getOutputStream());
+        }
+        catch (IOException ioe)
+        {
+            throw new SourceException("Couldn't copy " + getURI() + " to " + destination.getURI(), ioe);
+        }
+    }
+
+    /**
+     * @see org.apache.struts.flow.core.source.MoveableSource#moveTo(org.apache.struts.flow.core.source.Source)
+     */
+    public void moveTo(Source destination) throws SourceException
+    {
+        if (destination instanceof FileSource)
+        {
+            final File dest = ((FileSource) destination).getFile();
+            final File parent = dest.getParentFile();
+
+            if (parent != null)
+            {
+                parent.mkdirs(); // ensure parent directories exist
+            }
+
+            if (!m_file.renameTo(dest))
+            {
+                throw new SourceException("Couldn't move " + getURI() + " to " + destination.getURI());
+            }
+        }
+        else
+        {
+            SourceUtil.move(this, destination);
+        }
+
+    }
+
+    //----------------------------------------------------------------------------------
+    //  Private helper class for ModifiableSource implementation
+    //----------------------------------------------------------------------------------
+
+    /**
+     * A file outputStream that will rename the temp file to the destination file upon close()
+     * and discard the temp file upon cancel().
+     */
+    private static class FileSourceOutputStream extends FileOutputStream
+    {
+
+        private File m_tmpFile;
+        private boolean m_isClosed = false;
+        private FileSource m_source;
+
+        public FileSourceOutputStream(File tmpFile, FileSource source) throws IOException
+        {
+            super(tmpFile);
+            m_tmpFile = tmpFile;
+            m_source = source;
+        }
+
+        public void close() throws IOException
+        {
+            if (!m_isClosed)
+            {
+                super.close();
+                try
+                {
+                    // Delete destination file
+                    if (m_source.getFile().exists())
+                    {
+                        m_source.getFile().delete();
+                    }
+                    // Rename temp file to destination file
+                    if (!m_tmpFile.renameTo(m_source.getFile())) 
+                    {
+                       throw new IOException("Could not rename " + 
+                         m_tmpFile.getAbsolutePath() + 
+                         " to " + m_source.getFile().getAbsolutePath());
+                    }
+
+                }
+                finally
+                {
+                    // Ensure temp file is deleted, ie lock is released.
+                    // If there was a failure above, written data is lost.
+                    if (m_tmpFile.exists())
+                    {
+                        m_tmpFile.delete();
+                    }
+                    m_isClosed = true;
+                }
+            }
+
+        }
+
+        public boolean canCancel()
+        {
+            return !m_isClosed;
+        }
+
+        public void cancel() throws Exception
+        {
+            if (m_isClosed)
+            {
+                throw new IllegalStateException("Cannot cancel : outputstrem is already closed");
+            }
+
+            m_isClosed = true;
+            super.close();
+            m_tmpFile.delete();
+        }
+
+        public void finalize()
+        {
+            if (!m_isClosed && m_tmpFile.exists())
+            {
+                // Something wrong happened while writing : delete temp file
+                m_tmpFile.delete();
+            }
+        }
+
+        public FileSource getSource()
+        {
+            return m_source;
+        }
+    }
+}

Propchange: struts/flow/trunk/src/java/org/apache/struts/flow/core/source/impl/FileSource.java
------------------------------------------------------------------------------
    svn:executable = *

Added: struts/flow/trunk/src/java/org/apache/struts/flow/core/source/impl/FileSourceFactory.java
URL: http://svn.apache.org/viewcvs/struts/flow/trunk/src/java/org/apache/struts/flow/core/source/impl/FileSourceFactory.java?rev=349187&view=auto
==============================================================================
--- struts/flow/trunk/src/java/org/apache/struts/flow/core/source/impl/FileSourceFactory.java (added)
+++ struts/flow/trunk/src/java/org/apache/struts/flow/core/source/impl/FileSourceFactory.java Sat Nov 26 23:10:08 2005
@@ -0,0 +1,68 @@
+/* 
+ * Copyright 2002-2004 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.struts.flow.core.source.impl;
+
+import java.io.IOException;
+import java.net.MalformedURLException;
+import java.util.Map;
+
+import org.apache.struts.flow.core.source.Source;
+import org.apache.struts.flow.core.source.SourceFactory;
+import org.apache.struts.flow.core.source.URIAbsolutizer;
+import org.apache.struts.flow.core.source.SourceUtil;
+
+/**
+ * A factory for filesystem-based sources (see {@link FileSource}).
+ * 
+ * @avalon.component
+ * @avalon.service type=SourceFactory
+ * @x-avalon.info name=file-source
+ * @x-avalon.lifestyle type=singleton
+ * 
+ * @author <a href="mailto:dev@avalon.apache.org">Avalon Development Team</a>
+ * @version $Id: FileSourceFactory.java,v 1.4 2004/02/28 11:47:24 cziegeler Exp $
+ */
+public class FileSourceFactory implements SourceFactory, URIAbsolutizer
+{
+
+    /**
+     * @see org.apache.struts.flow.core.source.SourceFactory#getSource(java.lang.String, java.util.Map)
+     */
+    public Source getSource(String location, Map parameters) throws IOException, MalformedURLException
+    {
+        return new FileSource(location);
+    }
+
+    /**
+     * Does nothing, since {@link FileSource}s don't need to be released.
+     * 
+     * @see org.apache.struts.flow.core.source.SourceFactory#release(org.apache.struts.flow.core.source.Source)
+     */
+    public void release(Source source)
+    {
+        // Nothing to do here
+    }
+
+    public String absolutize(String baseURI, String location)
+    {
+        // Call the absolutize utility method with false for the normalizePath argument.
+        // This avoids the removal of "../" from the path.
+        // This way, the "../" will be resolved by the operating system, which might
+        // do things differently e.g. in case of symbolic links.
+        return SourceUtil.absolutize(baseURI, location, false, false);
+    }
+}

Propchange: struts/flow/trunk/src/java/org/apache/struts/flow/core/source/impl/FileSourceFactory.java
------------------------------------------------------------------------------
    svn:executable = *

Added: struts/flow/trunk/src/java/org/apache/struts/flow/core/source/impl/ResourceSource.java
URL: http://svn.apache.org/viewcvs/struts/flow/trunk/src/java/org/apache/struts/flow/core/source/impl/ResourceSource.java?rev=349187&view=auto
==============================================================================
--- struts/flow/trunk/src/java/org/apache/struts/flow/core/source/impl/ResourceSource.java (added)
+++ struts/flow/trunk/src/java/org/apache/struts/flow/core/source/impl/ResourceSource.java Sat Nov 26 23:10:08 2005
@@ -0,0 +1,130 @@
+/* 
+ * Copyright 2002-2004 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.struts.flow.core.source.impl;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.net.URLConnection;
+
+import org.apache.struts.flow.core.source.Source;
+import org.apache.struts.flow.core.source.SourceException;
+import org.apache.struts.flow.core.source.SourceNotFoundException;
+import org.apache.struts.flow.core.source.SourceUtil;
+import org.apache.struts.flow.core.source.SourceValidity;
+import org.apache.struts.flow.core.source.impl.validity.TimeStampValidity;
+
+/**
+ * Description of a source which is described by the resource protocol
+ * which gets a resource from the classloader.
+ *
+ * @author <a href="mailto:dev@avalon.apache.org">Avalon Development Team</a>
+ * @version CVS $Revision: 1.4 $ $Date: 2004/02/28 11:47:24 $
+ */
+public final class ResourceSource
+    extends AbstractSource
+    implements Source
+{
+    /** Location of the resource */
+    private URL m_location;
+    private String m_mimeType;
+
+    public ResourceSource( final String systemId ) throws MalformedURLException
+    {
+        final int pos = SourceUtil.indexOfSchemeColon(systemId);
+        if (pos == -1 || ! systemId.startsWith("://", pos))
+        {
+            throw new MalformedURLException("Invalid format for ResourceSource : " + systemId);
+        }
+        
+        setSystemId(systemId);
+        m_location = getClassLoader().getResource(systemId.substring( pos + 3 ));
+        setScheme(systemId.substring(0, pos));
+    }
+    
+    public boolean exists()
+    {
+        return m_location != null;
+    }
+    
+    protected void getInfos()
+    {
+        // Reset infos
+        super.getInfos();
+        m_mimeType = null;
+        
+        if (m_location == null) {
+            // Does not exist
+            return;
+        }
+        
+        URLConnection connection;
+        try
+        {
+            connection = m_location.openConnection();
+        }
+        catch(IOException ioe)
+        {
+            // Exists but unable to open it??
+            return;
+        }
+
+        setLastModified(connection.getLastModified());
+        setContentLength(connection.getContentLength());
+        m_mimeType = connection.getContentType();
+    }
+    
+    public String getMimeType()
+    {
+        return m_mimeType;
+    }
+
+    /**
+     * Return an <code>InputStream</code> object to read from the source.
+     *
+     * The returned stream must be closed by the calling code.
+     */
+    public InputStream getInputStream()
+        throws IOException, SourceException
+    {
+        if (!exists())
+        {
+            throw new SourceNotFoundException(getURI());
+        }
+        
+        return m_location.openStream();
+    }
+
+    /**
+     * Returns {@link TimeStampValidity} as resources may change in a directory-based classloader.
+     */
+    public SourceValidity getValidity()
+    {
+        return new TimeStampValidity(getLastModified());
+    }
+    
+    protected ClassLoader getClassLoader() {
+        ClassLoader loader = Thread.currentThread().getContextClassLoader();
+        if( loader == null )
+        {
+            loader = getClass().getClassLoader();
+        }
+        
+        return loader;
+    }
+}

Propchange: struts/flow/trunk/src/java/org/apache/struts/flow/core/source/impl/ResourceSource.java
------------------------------------------------------------------------------
    svn:executable = *

Added: struts/flow/trunk/src/java/org/apache/struts/flow/core/source/impl/ResourceSourceFactory.java
URL: http://svn.apache.org/viewcvs/struts/flow/trunk/src/java/org/apache/struts/flow/core/source/impl/ResourceSourceFactory.java?rev=349187&view=auto
==============================================================================
--- struts/flow/trunk/src/java/org/apache/struts/flow/core/source/impl/ResourceSourceFactory.java (added)
+++ struts/flow/trunk/src/java/org/apache/struts/flow/core/source/impl/ResourceSourceFactory.java Sat Nov 26 23:10:08 2005
@@ -0,0 +1,81 @@
+/* 
+ * Copyright 2002-2004 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.struts.flow.core.source.impl;
+
+import java.io.IOException;
+import java.net.MalformedURLException;
+import java.util.Map;
+
+import org.apache.struts.flow.core.Factory;
+import org.apache.struts.flow.core.Logger;
+
+import org.apache.struts.flow.core.source.Source;
+import org.apache.struts.flow.core.source.SourceException;
+import org.apache.struts.flow.core.source.SourceFactory;
+
+/**
+ * A factory for the Resource protocol
+ * 
+ * @avalon.component
+ * @avalon.service type=SourceFactory
+ * @x-avalon.info name=resource-source
+ * @x-avalon.lifestyle type=singleton
+ *
+ * @author <a href="mailto:dev@avalon.apache.org">Avalon Development Team</a>
+ * @version $Id: ResourceSourceFactory.java,v 1.4 2004/02/28 11:47:24 cziegeler Exp $
+ */
+public class ResourceSourceFactory implements SourceFactory
+{
+    /**
+     * Get a {@link Source} object.
+     * The factory creates a new {@link Source} object that can be used
+     * by the application. However, when this source object is not needed
+     * anymore it has to be released again using the {@link #release(Source)}
+     * method.
+     * 
+     * @param location   The URI to resolve - this URI includes the protocol.
+     * @param parameters This is optional.
+     */
+    public Source getSource( String location, Map parameters )
+        throws MalformedURLException, IOException, SourceException
+    {
+        if( getLogger().isDebugEnabled() )
+        {
+            final String message = "Creating source object for " + location;
+            getLogger().debug( message );
+        }
+        return new ResourceSource( location );
+    }
+    
+    /**
+     * Release a {@link Source} object.
+     */
+    public void release( Source source ) 
+    {
+        if( null != source && getLogger().isDebugEnabled() )
+        {
+            final String message = "Releasing source object for " + source.getURI();
+            getLogger().debug( message );
+        }
+        // do nothing here
+    }
+    
+    public Logger getLogger() {
+        return Factory.getLogger();
+    }
+    
+}

Propchange: struts/flow/trunk/src/java/org/apache/struts/flow/core/source/impl/ResourceSourceFactory.java
------------------------------------------------------------------------------
    svn:executable = *

Added: struts/flow/trunk/src/java/org/apache/struts/flow/core/source/impl/URLSource.java
URL: http://svn.apache.org/viewcvs/struts/flow/trunk/src/java/org/apache/struts/flow/core/source/impl/URLSource.java?rev=349187&view=auto
==============================================================================
--- struts/flow/trunk/src/java/org/apache/struts/flow/core/source/impl/URLSource.java (added)
+++ struts/flow/trunk/src/java/org/apache/struts/flow/core/source/impl/URLSource.java Sat Nov 26 23:10:08 2005
@@ -0,0 +1,352 @@
+/*
+ * Copyright 2002-2004 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.struts.flow.core.source.impl;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.UnsupportedEncodingException;
+import java.net.HttpURLConnection;
+import java.net.URL;
+import java.net.URLConnection;
+import java.net.URLDecoder;
+import java.util.Iterator;
+import java.util.Map;
+
+import org.apache.struts.flow.core.source.Source;
+import org.apache.struts.flow.core.source.SourceException;
+import org.apache.struts.flow.core.source.SourceParameters;
+import org.apache.struts.flow.core.source.SourceResolver;
+import org.apache.struts.flow.core.source.SourceUtil;
+import org.apache.struts.flow.core.source.SourceValidity;
+import org.apache.struts.flow.core.source.impl.validity.TimeStampValidity;
+
+/**
+ * Description of a source which is described by an URL.
+ *
+ * @author <a href="mailto:dev@avalon.apache.org">Avalon Development Team</a>
+ * @version CVS $Revision: 1.5 $ $Date: 2004/02/28 11:47:24 $
+ */
+public class URLSource extends AbstractSource implements Source
+{
+
+    /** The URL of the source */
+    protected URL m_url;
+
+    /** The connection for a real URL */
+    protected URLConnection m_connection;
+
+    /** The <code>SourceParameters</code> used for a post*/
+    protected SourceParameters m_parameters;
+
+    /** The encoding of the <code>SourceParameters</code>*/
+    protected String m_encoding;
+
+    /** Is this a post? */
+    protected boolean m_isPost = false;
+
+    /** Does this source exist ? */
+    protected boolean m_exists = false;
+
+    /** the prev returned SourceValidity */
+    protected SourceValidity m_cachedValidity;
+
+    protected long m_cachedLastModificationDate;
+
+    /** The content type (if known) */
+    protected String m_mimeType;
+
+    /**
+     * Constructor
+     */
+    public URLSource()
+    {
+    }
+
+    /**
+     * Initialize a new object from a <code>URL</code>.
+     * @param parameters This is optional
+     */
+    public void init(URL url, Map parameters) throws IOException
+    {
+        String systemId = url.toExternalForm();
+        setSystemId(systemId);
+        setScheme(SourceUtil.getScheme(systemId));
+
+        m_url = url;
+        m_isPost = false;
+        // get the default system encoding in case no encoding is specified
+        try {
+            m_encoding = System.getProperty("file.property", "ISO-8859-1");
+        } catch (SecurityException e) {
+            m_encoding = "ISO-8859-1"; 
+        }
+
+        if (null != parameters)
+        {
+            m_parameters = (SourceParameters) parameters.get(SourceResolver.URI_PARAMETERS);
+            final String method = (String) parameters.get(SourceResolver.METHOD);
+
+            if ("POST".equalsIgnoreCase(method))
+                m_isPost = true;
+
+            final String encoding = (String) parameters.get(SourceResolver.URI_ENCODING);
+            if (encoding != null && !"".equals(encoding))
+                m_encoding = encoding;
+        }
+
+        if (null != m_parameters && m_parameters.hasParameters() && !m_isPost)
+        {
+            StringBuffer urlBuffer = new StringBuffer(systemId);
+            String key;
+            final Iterator i = m_parameters.getParameterNames();
+            Iterator values;
+            String value;
+            boolean first = (systemId.indexOf('?') == -1);
+            if (first == true)
+                urlBuffer.append('?');
+            while (i.hasNext())
+            {
+                key = (String) i.next();
+                values = m_parameters.getParameterValues(key);
+                while (values.hasNext() == true)
+                {
+                    value = SourceUtil.encode((String) values.next(), m_encoding);
+                    if (first == false)
+                        urlBuffer.append('&');
+                    first = false;
+                    urlBuffer.append(key);
+                    urlBuffer.append('=');
+                    urlBuffer.append(value);
+                }
+            }
+
+            m_url = new URL(urlBuffer.toString());
+            m_parameters = null;
+        }
+    }
+
+    /**
+     * Get the last modification date and content length of the source.
+     * Any exceptions are ignored.
+     * Override this to get the real information
+     */
+    protected void getInfos()
+    {
+        // exists will be set below depending on the m_url type
+        m_exists = false;
+
+        if (!m_isPost)
+        {
+            try
+            {
+                if (null == m_connection)
+                {
+                    m_connection = m_url.openConnection();
+                    String userInfo = getUserInfo();
+                    if (m_url.getProtocol().startsWith("http") && userInfo != null){
+                        m_connection.setRequestProperty("Authorization", "Basic " + SourceUtil.encodeBASE64(userInfo));
+                    }
+                }
+                setLastModified(m_connection.getLastModified());
+                m_mimeType = m_connection.getContentType();
+                int contentLength = m_connection.getContentLength();
+                setContentLength(contentLength);
+                if ( m_connection instanceof HttpURLConnection )
+                {
+                    // check the status code for exists
+                    // if the url does not exists we might also get an IOException here!
+                    try 
+                    {
+                        final int statusCode = ((HttpURLConnection)m_connection).getResponseCode();
+                        if ( statusCode == 200 || statusCode == 304 )
+                        {
+                            m_exists = true;
+                        } 
+                        else
+                        {
+                            m_exists = false;
+                        }                        
+                    }
+                    catch (IOException ignore)
+                    {
+                        m_exists = false;
+                    }
+                        
+                } 
+                else 
+                {
+                    m_exists = contentLength > 0;
+                }
+            }
+            catch (IOException ignore)
+            {
+                super.getInfos();
+            }
+        }
+        else
+        {
+            // do not open m_connection when using post!
+            super.getInfos();
+        }
+    }
+
+    /**
+     * Does this source exist ?
+     */
+    public boolean exists()
+    {
+        checkInfos();
+        return m_exists;
+    }
+
+    /**
+     * Return an <code>InputStream</code> object to read from the source.
+     *
+     * The returned stream must be closed by the calling code.
+     *
+     * @throws SourceException if file not found or
+     *         HTTP location does not exist.
+     * @throws IOException if I/O error occured.
+     */
+    public InputStream getInputStream() throws IOException, SourceException
+    {
+        checkInfos();
+        InputStream input = null;
+        if (m_connection == null)
+        {
+            m_connection = m_url.openConnection();
+
+            String userInfo = getUserInfo();
+            if (m_url.getProtocol().startsWith("http") && userInfo != null)
+            {
+                m_connection.setRequestProperty("Authorization", "Basic " + SourceUtil.encodeBASE64(userInfo));
+            }
+
+            // do a post operation
+            if (m_connection instanceof HttpURLConnection && m_isPost)
+            {
+                StringBuffer buffer = new StringBuffer(2000);
+                String key;
+                Iterator i = m_parameters.getParameterNames();
+                Iterator values;
+                String value;
+                boolean first = true;
+                while (i.hasNext())
+                {
+                    key = (String) i.next();
+                    values = m_parameters.getParameterValues(key);
+                    while (values.hasNext() == true)
+                    {
+                        value = SourceUtil.encode((String) values.next(), m_encoding);
+                        if (first == false)
+                            buffer.append('&');
+                        first = false;
+                        buffer.append(key.toString());
+                        buffer.append('=');
+                        buffer.append(value);
+                    }
+                }
+                HttpURLConnection httpCon = (HttpURLConnection) m_connection;
+                httpCon.setDoInput(true);
+
+                if (buffer.length() > 1)
+                { // only post if we have parameters
+                    String postString = buffer.toString();
+                    httpCon.setRequestMethod("POST"); // this is POST
+                    httpCon.setDoOutput(true);
+                    httpCon.setRequestProperty("Content-type", "application/x-www-form-urlencoded");
+
+                    // A content-length header must be contained in a POST request
+                    httpCon.setRequestProperty("Content-length", Integer.toString(postString.length()));
+                    java.io.OutputStream out = new java.io.BufferedOutputStream(httpCon.getOutputStream());
+                    out.write(postString.getBytes());
+                    out.close();
+                }
+                input = httpCon.getInputStream();
+                m_connection = null; // make sure a new m_connection is created next time
+                return input;
+            }
+        }
+        input = m_connection.getInputStream();
+        m_connection = null; // make sure a new m_connection is created next time
+        return input;
+    }
+
+    /**
+     *  Get the Validity object. This can either wrap the last modification
+     *  date or the expires information or...
+     *  If it is currently not possible to calculate such an information
+     *  <code>null</code> is returned.
+     */
+    public SourceValidity getValidity()
+    {
+        final long lm = getLastModified();
+        if (lm > 0)
+        {
+            if (lm == m_cachedLastModificationDate)
+                return m_cachedValidity;
+
+            m_cachedLastModificationDate = lm;
+            m_cachedValidity = new TimeStampValidity(lm);
+            return m_cachedValidity;
+        }
+        return null;
+    }
+
+    /**
+     * Refresh this object and update the last modified date
+     * and content length.
+     */
+    public void refresh()
+    {
+        // reset m_connection
+        m_connection = null;
+        super.refresh();
+    }
+
+    /**
+     * The mime-type of the content described by this object.
+     * If the source is not able to determine the mime-type by itself
+     * this can be null.
+     */
+    public String getMimeType()
+    {
+        return m_mimeType;
+    }
+
+    /**
+     * The decoded userinfo for this source.
+     * null, if no userinfo exists
+     */
+    protected String getUserInfo()
+    {
+        if (m_url == null) return null;
+        String ui = m_url.getUserInfo();
+        if (ui == null) return null;
+
+        try
+        {
+         ui = URLDecoder.decode(ui,"UTF-8");
+        }
+        catch (UnsupportedEncodingException e)
+        {
+         // Platform does not support UTF-8. This should never happen.
+         // e.printStackTrace();
+        }
+        return ui;
+    }
+}

Propchange: struts/flow/trunk/src/java/org/apache/struts/flow/core/source/impl/URLSource.java
------------------------------------------------------------------------------
    svn:executable = *

Added: struts/flow/trunk/src/java/org/apache/struts/flow/core/source/impl/URLSourceFactory.java
URL: http://svn.apache.org/viewcvs/struts/flow/trunk/src/java/org/apache/struts/flow/core/source/impl/URLSourceFactory.java?rev=349187&view=auto
==============================================================================
--- struts/flow/trunk/src/java/org/apache/struts/flow/core/source/impl/URLSourceFactory.java (added)
+++ struts/flow/trunk/src/java/org/apache/struts/flow/core/source/impl/URLSourceFactory.java Sat Nov 26 23:10:08 2005
@@ -0,0 +1,115 @@
+/* 
+ * Copyright 2002-2004 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.struts.flow.core.source.impl;
+
+import java.io.IOException;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.util.Map;
+
+import org.apache.struts.flow.core.Factory;
+import org.apache.struts.flow.core.Logger;
+
+import org.apache.struts.flow.core.source.Source;
+import org.apache.struts.flow.core.source.SourceFactory;
+
+/**
+ * A factory for a {@link URL} wrapper
+ * 
+ * @avalon.component
+ * @avalon.service type=SourceFactory
+ * @x-avalon.info name=url-source
+ * @x-avalon.lifestyle type=singleton
+ *
+ * @author <a href="mailto:dev@avalon.apache.org">Avalon Development Team</a>
+ * @version $Id: URLSourceFactory.java,v 1.4 2004/02/28 11:47:24 cziegeler Exp $
+ */
+public class URLSourceFactory implements SourceFactory
+{
+
+    /**
+     * Create an URL-based source. This class actually creates an {@link URLSource}, but if another
+     * implementation is needed, subclasses can override this method.
+     */
+    protected Source createURLSource(URL url, Map parameters) throws MalformedURLException, IOException
+    {
+        URLSource result = new URLSource();
+        result.init(url, parameters);
+        return result;
+    }
+
+    /**
+     * Create an file-based source. This class actually creates an {@link FileSource}, but if another
+     * implementation is needed, subclasses can override this method.
+     */
+    protected Source createFileSource(String uri) throws MalformedURLException, IOException
+    {
+        return new FileSource(uri);
+    }
+
+    /**
+     * @see org.apache.struts.flow.core.source.SourceFactory#getSource(java.lang.String, java.util.Map)
+     */
+    public Source getSource(String uri, Map parameters) throws MalformedURLException, IOException
+    {
+        if (getLogger().isDebugEnabled())
+        {
+            final String message = "Creating source object for " + uri;
+            getLogger().debug(message);
+        }
+
+        // First check if it's a file
+        if (uri.startsWith("file:"))
+        {
+            // Yes : return a file source
+            return createFileSource(uri);
+        }
+        else
+        {
+            // Not a "file:" : create an URLSource
+            // First try to create the URL
+            URL url;
+            try
+            {
+                url = new URL(uri);
+            }
+            catch (MalformedURLException mue)
+            {
+                // Maybe a file name containing a ':' ?
+                if (getLogger().isDebugEnabled())
+                {
+                    this.getLogger().debug("URL " + uri + " is malformed. Assuming it's a file path.", mue);
+                }
+                return createFileSource(uri);
+            }
+
+            return createURLSource(url, parameters);
+        }
+    }
+
+    /**
+     * @see org.apache.struts.flow.core.source.SourceFactory#release(org.apache.struts.flow.core.source.Source)
+     */
+    public void release(Source source)
+    {
+        // do nothing here
+    }
+    
+    public Logger getLogger() {
+        return Factory.getLogger();
+    }
+}

Propchange: struts/flow/trunk/src/java/org/apache/struts/flow/core/source/impl/URLSourceFactory.java
------------------------------------------------------------------------------
    svn:executable = *

Added: struts/flow/trunk/src/java/org/apache/struts/flow/core/source/impl/validity/AbstractAggregatedValidity.java
URL: http://svn.apache.org/viewcvs/struts/flow/trunk/src/java/org/apache/struts/flow/core/source/impl/validity/AbstractAggregatedValidity.java?rev=349187&view=auto
==============================================================================
--- struts/flow/trunk/src/java/org/apache/struts/flow/core/source/impl/validity/AbstractAggregatedValidity.java (added)
+++ struts/flow/trunk/src/java/org/apache/struts/flow/core/source/impl/validity/AbstractAggregatedValidity.java Sat Nov 26 23:10:08 2005
@@ -0,0 +1,63 @@
+/* 
+ * Copyright 2002-2004 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.struts.flow.core.source.impl.validity;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.List;
+
+import org.apache.struts.flow.core.source.SourceValidity;
+
+/**
+ * The base class for the aggregation implementations
+ *
+ * @author <a href="mailto:dev@avalon.apache.org">Avalon Development Team</a>
+ * @version CVS $Revision: 1.4 $ $Date: 2004/02/28 11:47:17 $
+ */
+public abstract class AbstractAggregatedValidity
+    implements SourceValidity
+{
+    final ArrayList m_list = new ArrayList();
+
+    public void add( final SourceValidity validity )
+    {
+        m_list.add( validity );
+    }
+
+    public String toString()
+    {
+        final StringBuffer sb = new StringBuffer( "SourceValidity " );
+        for( final Iterator i = m_list.iterator(); i.hasNext(); )
+        {
+            sb.append( i.next() );
+            if( i.hasNext() ) sb.append( ':' );
+        }
+        return sb.toString();
+    }
+    
+    public List getValidities() 
+    {
+        return Collections.unmodifiableList(m_list);
+    }
+    
+    SourceValidity getValidity(final int index) 
+    {
+        return (SourceValidity) m_list.get(index);
+    }
+    
+}

Propchange: struts/flow/trunk/src/java/org/apache/struts/flow/core/source/impl/validity/AbstractAggregatedValidity.java
------------------------------------------------------------------------------
    svn:executable = *

Added: struts/flow/trunk/src/java/org/apache/struts/flow/core/source/impl/validity/AggregatedValidity.java
URL: http://svn.apache.org/viewcvs/struts/flow/trunk/src/java/org/apache/struts/flow/core/source/impl/validity/AggregatedValidity.java?rev=349187&view=auto
==============================================================================
--- struts/flow/trunk/src/java/org/apache/struts/flow/core/source/impl/validity/AggregatedValidity.java (added)
+++ struts/flow/trunk/src/java/org/apache/struts/flow/core/source/impl/validity/AggregatedValidity.java Sat Nov 26 23:10:08 2005
@@ -0,0 +1,89 @@
+/* 
+ * Copyright 2002-2004 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.struts.flow.core.source.impl.validity;
+
+import java.util.Iterator;
+import java.util.List;
+
+import org.apache.struts.flow.core.source.SourceValidity;
+
+/**
+ * A validation object using a List.
+ *
+ * @author <a href="mailto:dev@avalon.apache.org">Avalon Development Team</a>
+ * @version CVS $Revision: 1.4 $ $Date: 2004/02/28 11:47:17 $
+ */
+public final class AggregatedValidity
+    extends AbstractAggregatedValidity
+    implements SourceValidity
+{
+    /**
+     * Check if the component is still valid.
+     * If <code>0</code> is returned the isValid(SourceValidity) must be
+     * called afterwards!
+     * If -1 is returned, the component is not valid anymore and if +1
+     * is returnd, the component is valid.
+     */
+    public int isValid()
+    {
+        for( final Iterator i = m_list.iterator(); i.hasNext(); )
+        {
+            final int v = ( (SourceValidity)i.next() ).isValid();
+            if( v < 1 )
+            {
+                return v;
+            }
+        }
+        return 1;
+    }
+
+    public int isValid( final SourceValidity validity )
+    {
+        if( validity instanceof AggregatedValidity )
+        {
+            final AggregatedValidity other = (AggregatedValidity)validity;
+            final List otherList = other.m_list;
+            if( m_list.size() != otherList.size() )
+            {
+                return -1;
+            }
+
+            for( final Iterator i = m_list.iterator(), j = otherList.iterator(); i.hasNext(); )
+            {
+                final SourceValidity srcA = (SourceValidity)i.next();
+                final SourceValidity srcB = (SourceValidity)j.next();
+                int result = srcA.isValid();
+                if ( result == -1) 
+                {
+                    return -1;
+                }
+                if ( result == 0 )
+                {
+                    result = srcA.isValid( srcB );
+                    if ( result < 1)
+                    {
+                        return result;
+                    }
+                }
+            }
+            return 1;
+        }
+        return -1;
+    }
+
+}
+

Propchange: struts/flow/trunk/src/java/org/apache/struts/flow/core/source/impl/validity/AggregatedValidity.java
------------------------------------------------------------------------------
    svn:executable = *

Added: struts/flow/trunk/src/java/org/apache/struts/flow/core/source/impl/validity/DeferredAggregatedValidity.java
URL: http://svn.apache.org/viewcvs/struts/flow/trunk/src/java/org/apache/struts/flow/core/source/impl/validity/DeferredAggregatedValidity.java?rev=349187&view=auto
==============================================================================
--- struts/flow/trunk/src/java/org/apache/struts/flow/core/source/impl/validity/DeferredAggregatedValidity.java (added)
+++ struts/flow/trunk/src/java/org/apache/struts/flow/core/source/impl/validity/DeferredAggregatedValidity.java Sat Nov 26 23:10:08 2005
@@ -0,0 +1,147 @@
+/* 
+ * Copyright 2002-2004 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.struts.flow.core.source.impl.validity;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.ListIterator;
+
+import org.apache.struts.flow.core.source.SourceValidity;
+
+/**
+ * A validation object using a List.
+ * This validity object does the same as the {@link AggregatedValidity}
+ * object, but the contained validity objects are only fetched when
+ * required.
+ *
+ * @author <a href="mailto:dev@avalon.apache.org">Avalon Development Team</a>
+ * @version CVS $Revision: 1.4 $ $Date: 2004/02/28 11:47:17 $
+ */
+public final class DeferredAggregatedValidity
+        extends AbstractAggregatedValidity
+    implements SourceValidity
+{
+
+    public void add( final DeferredValidity validity )
+    {
+        m_list.add( validity );
+    }
+
+    /**
+     * Check if the component is still valid.
+     * If <code>0</code> is returned the isValid(SourceValidity) must be
+     * called afterwards!
+     * If -1 is returned, the component is not valid anymore and if +1
+     * is returnd, the component is valid.
+     */
+    public int isValid()
+    {
+        for( final ListIterator i = m_list.listIterator(); i.hasNext(); )
+        {
+            final Object o = i.next();
+            final SourceValidity validity;
+            if (o instanceof SourceValidity) {
+                validity = (SourceValidity)o;
+            } else {
+                validity = ((DeferredValidity)o).getValidity();
+                i.set(validity);
+            }
+            final int v = validity.isValid();
+            if( v < 1 )
+            {
+                return v;
+            }
+        }
+        return 1;
+    }
+
+    public int isValid( final SourceValidity validity )
+    {
+        AbstractAggregatedValidity aggregatedValidity = null;
+        
+        if (validity instanceof AbstractAggregatedValidity) 
+        {
+            aggregatedValidity = (AbstractAggregatedValidity)validity;
+        }
+        
+        if ( null != aggregatedValidity) 
+        {
+            ArrayList otherList = aggregatedValidity.m_list;
+            if( m_list.size() != otherList.size() )
+            {
+                return -1;
+            }
+
+            for(int i=0; i < m_list.size(); i++) {
+                final SourceValidity srcA = this.getValidity(i);
+                int result = srcA.isValid();
+                if ( result == -1) 
+                {
+                    return -1;
+                }
+                if ( result == 0 )
+                {
+                    final SourceValidity srcB = aggregatedValidity.getValidity(i);
+                    result = srcA.isValid( srcB );
+                    if ( result < 1)
+                    {
+                        return result;
+                    }
+                }
+            }
+            return 1;
+        }
+        return -1;
+    }
+
+    public String toString()
+    {
+        final StringBuffer sb = new StringBuffer( "SourceValidity " );
+        for( final Iterator i = m_list.iterator(); i.hasNext(); )
+        {
+            sb.append( i.next() );
+            if( i.hasNext() ) sb.append( ':' );
+        }
+        return sb.toString();
+    }
+    
+    SourceValidity getValidity(final int index) 
+    {
+        final Object o = m_list.get(index);
+        final SourceValidity validity;
+        if (o instanceof SourceValidity) {
+            validity = (SourceValidity)o;
+        } else {
+            validity = ((DeferredValidity)o).getValidity();
+            m_list.set(index, validity);
+        }
+        return validity;
+    }
+    
+    private void writeObject(java.io.ObjectOutputStream out)
+         throws IOException
+    {
+        // resolve all deferred source validities first
+        for(int i=0; i<m_list.size();i++) {
+            this.getValidity(i);
+        }
+        out.defaultWriteObject();
+    }
+
+}
+

Propchange: struts/flow/trunk/src/java/org/apache/struts/flow/core/source/impl/validity/DeferredAggregatedValidity.java
------------------------------------------------------------------------------
    svn:executable = *

Added: struts/flow/trunk/src/java/org/apache/struts/flow/core/source/impl/validity/DeferredValidity.java
URL: http://svn.apache.org/viewcvs/struts/flow/trunk/src/java/org/apache/struts/flow/core/source/impl/validity/DeferredValidity.java?rev=349187&view=auto
==============================================================================
--- struts/flow/trunk/src/java/org/apache/struts/flow/core/source/impl/validity/DeferredValidity.java (added)
+++ struts/flow/trunk/src/java/org/apache/struts/flow/core/source/impl/validity/DeferredValidity.java Sat Nov 26 23:10:08 2005
@@ -0,0 +1,35 @@
+/* 
+ * Copyright 2002-2004 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.struts.flow.core.source.impl.validity;
+
+import org.apache.struts.flow.core.source.SourceValidity;
+
+
+/**
+ * This object delivers a validity object if required. 
+ * Used by the {@link DeferredAggregatedValidity}
+ *
+ * @author <a href="mailto:dev@avalon.apache.org">Avalon Development Team</a>
+ * @version CVS $Revision: 1.4 $ $Date: 2004/02/28 11:47:17 $
+ */
+public interface DeferredValidity {
+
+    /** 
+     * Return the validity
+     */
+    SourceValidity getValidity();
+}

Propchange: struts/flow/trunk/src/java/org/apache/struts/flow/core/source/impl/validity/DeferredValidity.java
------------------------------------------------------------------------------
    svn:executable = *

Added: struts/flow/trunk/src/java/org/apache/struts/flow/core/source/impl/validity/ExpiresValidity.java
URL: http://svn.apache.org/viewcvs/struts/flow/trunk/src/java/org/apache/struts/flow/core/source/impl/validity/ExpiresValidity.java?rev=349187&view=auto
==============================================================================
--- struts/flow/trunk/src/java/org/apache/struts/flow/core/source/impl/validity/ExpiresValidity.java (added)
+++ struts/flow/trunk/src/java/org/apache/struts/flow/core/source/impl/validity/ExpiresValidity.java Sat Nov 26 23:10:08 2005
@@ -0,0 +1,73 @@
+/* 
+ * Copyright 2002-2004 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.struts.flow.core.source.impl.validity;
+
+import org.apache.struts.flow.core.source.SourceValidity;
+
+/**
+ * A validation object that holds an expiration date.
+ * When the defined time/date has arrived, this validity object is 
+ * not valid any more.
+ *
+ * @author <a href="mailto:dev@avalon.apache.org">Avalon Development Team</a>
+ * @version CVS $Revision: 1.4 $ $Date: 2004/02/28 11:47:17 $
+ */
+public final class ExpiresValidity
+    implements SourceValidity
+{
+    private long expires;
+
+    /**
+     * Constructor
+     * @param expires The delta from now when this validity object gets invalid.
+     */
+    public ExpiresValidity( long expires ) 
+    {
+        this.expires = System.currentTimeMillis() + expires;
+    }
+
+    /**
+     * Checks if the expires date is already reached.
+     * 
+     * @see org.apache.struts.flow.core.source.SourceValidity#isValid()
+     */
+    public int isValid() 
+    {
+        final long currentTime = System.currentTimeMillis();
+        return (currentTime <= this.expires ? SourceValidity.VALID : SourceValidity.INVALID);
+    }
+
+    /**
+     * This method is never invoked as {@link #isValid()} can always perform
+     * the complete check.
+     * 
+     * @see org.apache.struts.flow.core.source.SourceValidity#isValid(SourceValidity)
+     */
+    public int isValid( SourceValidity newValidity ) 
+    {
+        return SourceValidity.INVALID;
+    }
+
+    /**
+     * 
+     * @see java.lang.Object#toString()
+     */
+    public String toString() 
+    {
+        return "ExpiresValidity: " + expires;
+    }
+}

Propchange: struts/flow/trunk/src/java/org/apache/struts/flow/core/source/impl/validity/ExpiresValidity.java
------------------------------------------------------------------------------
    svn:executable = *

Added: struts/flow/trunk/src/java/org/apache/struts/flow/core/source/impl/validity/FileTimeStampValidity.java
URL: http://svn.apache.org/viewcvs/struts/flow/trunk/src/java/org/apache/struts/flow/core/source/impl/validity/FileTimeStampValidity.java?rev=349187&view=auto
==============================================================================
--- struts/flow/trunk/src/java/org/apache/struts/flow/core/source/impl/validity/FileTimeStampValidity.java (added)
+++ struts/flow/trunk/src/java/org/apache/struts/flow/core/source/impl/validity/FileTimeStampValidity.java Sat Nov 26 23:10:08 2005
@@ -0,0 +1,89 @@
+/* 
+ * Copyright 2002-2004 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.struts.flow.core.source.impl.validity;
+
+import java.io.File;
+
+import org.apache.struts.flow.core.source.SourceValidity;
+
+/**
+ * A validation object for time-stamps.
+ *
+ * @author <a href="mailto:dev@avalon.apache.org">Avalon Development Team</a>
+ * @version CVS $Revision: 1.4 $
+ */
+public final class FileTimeStampValidity
+    implements SourceValidity
+{
+    private long m_timeStamp;
+    private File m_file;
+
+    public FileTimeStampValidity( final String filename )
+    {
+        this( new File( filename ) );
+    }
+
+    public FileTimeStampValidity( final File file )
+    {
+        this( file, file.lastModified() );
+    }
+
+    public FileTimeStampValidity( final File file,
+                                  final long timeStamp )
+    {
+        m_file = file;
+        m_timeStamp = timeStamp;
+    }
+
+    /**
+     * Check if the component is still valid.
+     * If <code>0</code> is returned the isValid(SourceValidity) must be
+     * called afterwards!
+     * If -1 is returned, the component is not valid anymore and if +1
+     * is returnd, the component is valid.
+     */
+    public int isValid()
+    {
+        return ( m_file.lastModified() == m_timeStamp ? 1 : -1 );
+    }
+
+    public int isValid( final SourceValidity newValidity )
+    {
+        if( newValidity instanceof FileTimeStampValidity )
+        {
+            final long timeStamp =
+                ( (FileTimeStampValidity)newValidity ).getTimeStamp();
+            return ( m_timeStamp == timeStamp ? 1 : -1);
+        }
+        return -1;
+    }
+
+    public File getFile()
+    {
+        return this.m_file;
+    }
+
+    public long getTimeStamp()
+    {
+        return this.m_timeStamp;
+    }
+
+    public String toString()
+    {
+        return "FileTimeStampValidity: " + m_file.getPath() + ": " + this.m_timeStamp;
+    }
+}

Propchange: struts/flow/trunk/src/java/org/apache/struts/flow/core/source/impl/validity/FileTimeStampValidity.java
------------------------------------------------------------------------------
    svn:executable = *

Added: struts/flow/trunk/src/java/org/apache/struts/flow/core/source/impl/validity/NOPValidity.java
URL: http://svn.apache.org/viewcvs/struts/flow/trunk/src/java/org/apache/struts/flow/core/source/impl/validity/NOPValidity.java?rev=349187&view=auto
==============================================================================
--- struts/flow/trunk/src/java/org/apache/struts/flow/core/source/impl/validity/NOPValidity.java (added)
+++ struts/flow/trunk/src/java/org/apache/struts/flow/core/source/impl/validity/NOPValidity.java Sat Nov 26 23:10:08 2005
@@ -0,0 +1,57 @@
+/* 
+ * Copyright 2002-2004 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.struts.flow.core.source.impl.validity;
+
+import org.apache.struts.flow.core.source.SourceValidity;
+
+/**
+ * A validation object which is always valid.
+ *
+ * @author <a href="mailto:dev@avalon.apache.org">Avalon Development Team</a>
+ * @version CVS $Revision: 1.4 $ $Date: 2004/02/28 11:47:17 $
+ */
+public final class NOPValidity
+    implements SourceValidity
+{
+    public static final SourceValidity SHARED_INSTANCE = new NOPValidity();
+
+    /**
+     * Check if the component is still valid.
+     * If <code>0</code> is returned the isValid(SourceValidity) must be
+     * called afterwards!
+     * If -1 is returned, the component is not valid anymore and if +1
+     * is returnd, the component is valid.
+     */
+    public int isValid()
+    {
+        return 1;
+    }
+
+    public int isValid( final SourceValidity newValidity )
+    {
+        if (newValidity instanceof NOPValidity)
+        {
+            return 1;
+        }
+        return -1;
+    }
+
+    public String toString()
+    {
+        return "NOPValidity";
+    }
+}

Propchange: struts/flow/trunk/src/java/org/apache/struts/flow/core/source/impl/validity/NOPValidity.java
------------------------------------------------------------------------------
    svn:executable = *

Added: struts/flow/trunk/src/java/org/apache/struts/flow/core/source/impl/validity/TimeStampValidity.java
URL: http://svn.apache.org/viewcvs/struts/flow/trunk/src/java/org/apache/struts/flow/core/source/impl/validity/TimeStampValidity.java?rev=349187&view=auto
==============================================================================
--- struts/flow/trunk/src/java/org/apache/struts/flow/core/source/impl/validity/TimeStampValidity.java (added)
+++ struts/flow/trunk/src/java/org/apache/struts/flow/core/source/impl/validity/TimeStampValidity.java Sat Nov 26 23:10:08 2005
@@ -0,0 +1,69 @@
+/* 
+ * Copyright 2002-2004 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.struts.flow.core.source.impl.validity;
+
+import org.apache.struts.flow.core.source.SourceValidity;
+
+/**
+ * A validation object for time-stamps.
+ *
+ * @author <a href="mailto:dev@avalon.apache.org">Avalon Development Team</a>
+ * @version CVS $Revision: 1.4 $ $Date: 2004/02/28 11:47:17 $
+ */
+public final class TimeStampValidity
+    implements SourceValidity
+{
+    private long m_timeStamp;
+
+    public TimeStampValidity( final long timeStamp )
+    {
+        m_timeStamp = timeStamp;
+    }
+
+    /**
+     * Check if the component is still valid.
+     * If <code>0</code> is returned the isValid(SourceValidity) must be
+     * called afterwards!
+     * If -1 is returned, the component is not valid anymore and if +1
+     * is returnd, the component is valid.
+     */
+    public int isValid()
+    {
+        return 0;
+    }
+
+    public int isValid( SourceValidity newValidity )
+    {
+        if( newValidity instanceof TimeStampValidity )
+        {
+            final long timeStamp =
+                ( (TimeStampValidity)newValidity ).getTimeStamp();
+            return (m_timeStamp == timeStamp ? +1 : -1);
+        }
+        return -1;
+    }
+
+    public long getTimeStamp()
+    {
+        return m_timeStamp;
+    }
+
+    public String toString()
+    {
+        return "TimeStampValidity: " + m_timeStamp;
+    }
+}

Propchange: struts/flow/trunk/src/java/org/apache/struts/flow/core/source/impl/validity/TimeStampValidity.java
------------------------------------------------------------------------------
    svn:executable = *

Modified: struts/flow/trunk/src/java/org/apache/struts/flow/ibatis/SqlMap.java
URL: http://svn.apache.org/viewcvs/struts/flow/trunk/src/java/org/apache/struts/flow/ibatis/SqlMap.java?rev=349187&r1=349186&r2=349187&view=diff
==============================================================================
--- struts/flow/trunk/src/java/org/apache/struts/flow/ibatis/SqlMap.java (original)
+++ struts/flow/trunk/src/java/org/apache/struts/flow/ibatis/SqlMap.java Sat Nov 26 23:10:08 2005
@@ -20,6 +20,7 @@
 import com.ibatis.sqlmap.engine.impl.*;
 import com.ibatis.sqlmap.client.*;
 import org.apache.struts.flow.core.*;
+import org.apache.struts.flow.core.javascript.*;
 import org.apache.struts.flow.sugar.*;
 
 import org.mozilla.javascript.JavaScriptException;
@@ -148,9 +149,9 @@
                     
                     Map params = null;
                     if (args.length == 1 && args[0] instanceof Scriptable) {
-                        params = JSFlow.jsobjectToMap((Scriptable)args[0]);
+                        params = ConversionHelper.jsobjectToMap((Scriptable)args[0]);
                     } else {
-                        params = JSFlow.jsobjectToMap(thisObj);
+                        params = ConversionHelper.jsobjectToMap(thisObj);
                     }
                     String stmName = namespace+"."+name;
                     Object result = null;

Modified: struts/flow/trunk/src/java/org/apache/struts/flow/portlet/FlowPortlet.java
URL: http://svn.apache.org/viewcvs/struts/flow/trunk/src/java/org/apache/struts/flow/portlet/FlowPortlet.java?rev=349187&r1=349186&r2=349187&view=diff
==============================================================================
--- struts/flow/trunk/src/java/org/apache/struts/flow/portlet/FlowPortlet.java (original)
+++ struts/flow/trunk/src/java/org/apache/struts/flow/portlet/FlowPortlet.java Sat Nov 26 23:10:08 2005
@@ -14,11 +14,14 @@
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
 import org.apache.struts.flow.core.Factory;
-import org.apache.struts.flow.core.JavaScriptInterpreter;
+import org.apache.struts.flow.core.javascript.fom.FOM_JavaScriptInterpreter;
+import org.apache.struts.flow.core.Interpreter;
+import org.apache.struts.flow.core.javascript.ConversionHelper;
 import org.apache.struts.flow.core.DefaultCallVariableRegistrar;
 import org.apache.struts.flow.sugar.SugarWrapFactory;
 import org.apache.commons.chain.*;
 import org.apache.commons.chain.web.portlet.*;
+import org.apache.struts.flow.core.source.impl.ChainSourceResolver;
 import java.util.*;
 import java.io.*;
 import org.mozilla.javascript.Scriptable;
@@ -26,25 +29,26 @@
 /**  Description of the Class */
 public class FlowPortlet extends GenericPortlet {
     
-    private JavaScriptInterpreter interp;
+    private CompilingInterpreter interp;
     
     public void init() {
         
         Factory.setLogger(new CommonsLogger());
         Factory.getContinuationsManager().setDefaultTimeToLive(10 * 60 * 1000);
         interp = createInterpreter();
-        interp.register(getInitParameter("path"));
+        interp.register(getInitParameter("scriptPath"));
     }
     
-    private JavaScriptInterpreter createInterpreter() {
-        JavaScriptInterpreter interp = new JavaScriptInterpreter();
+    private CompilingInterpreter createInterpreter() {
+        FOM_JavaScriptInterpreter interp = new FOM_JavaScriptInterpreter();
+        interp.setSourceResolver(new ChainSourceResolver(new PortletWebContext(getPortletContext(), null, null)));
         interp.setDebugger(false);
         interp.setCheckTime(0);
         interp.setReloadScripts(true);
         interp.setWrapFactory(new SugarWrapFactory());
         interp.initialize();
-        interp.register("/system.js");
-        //interp.addVariableRegistrar(new DefaultCallVariableRegistrar(Struts.class, "struts"));
+        interp.register("/org/apache/struts/flow/core/javascript/fom/fom_system.js");
+        interp.addVariableRegistrar(new DefaultCallVariableRegistrar(Portlet.class, "portlet"));
         //interp.addVariableRegistrar(new DefaultCallVariableRegistrar(SqlMap.class, "sqlMap"));
         return interp;
     }
@@ -77,17 +81,21 @@
             // --- start a new flow
 
             List args = new LinkedList();
-
-            // call control script function
-            interp.callFunction(func, args, context);
+            
+            try {
+                // call control script function
+                interp.callFunction(func, args, context);
+            } catch (Exception ex) {
+                throw new PortletException("Unable to execute flow script", ex);
+            }
 
             // retrieve page, continuation ID, and attributes from chain context
-            String page = (String) JSFlow.jsobjectToObject(context.get(Constants.FORWARD_NAME_KEY));
+            String page = (String) ConversionHelper.jsobjectToObject(context.get(Constants.FORWARD_NAME_KEY));
             contid = (String) context.get(Constants.CONTINUATION_ID_KEY);
             Scriptable bizdata = (Scriptable) context.get(Constants.BIZ_DATA_KEY);
             Map atts = null;
             if (bizdata != null) {
-                atts = JSFlow.jsobjectToMap(bizdata);
+                atts = ConversionHelper.jsobjectToMap(bizdata);
             }    
             dispatchToPage(request, response, page, contid, atts);
         } else {
@@ -96,7 +104,11 @@
             // kick off continuation
             context.put("id", "5");
             
-            interp.handleContinuation(contid, new LinkedList(), context);
+            try {
+                interp.handleContinuation(contid, new LinkedList(), context);
+            } catch (Exception ex) {
+                throw new PortletException("Unable to execute flow script", ex);
+            }
 
             // retrieve page, continuation ID, and attributes from chain context
             String page = (String) context.get(Constants.FORWARD_NAME_KEY);
@@ -104,7 +116,7 @@
             Scriptable bizdata = (Scriptable) context.get(Constants.BIZ_DATA_KEY);
             Map atts = null;
             if (bizdata != null) {
-                atts = JSFlow.jsobjectToMap(bizdata);
+                atts = ConversionHelper.jsobjectToMap(bizdata);
             }    
            
             dispatchToPage(request, response, page, contid, atts);
@@ -137,7 +149,7 @@
                 Iterator attkeys = atts.keySet().iterator();
                 while (attkeys.hasNext()) {
                     String attkey = (String) attkeys.next();
-                    request.setAttribute(attkey, JSFlow.jsobjectToObject(atts.get(attkey)));
+                    request.setAttribute(attkey, ConversionHelper.jsobjectToObject(atts.get(attkey)));
                 }
             }    
 

Added: struts/flow/trunk/src/java/org/apache/struts/flow/portlet/Portlet.java
URL: http://svn.apache.org/viewcvs/struts/flow/trunk/src/java/org/apache/struts/flow/portlet/Portlet.java?rev=349187&view=auto
==============================================================================
--- struts/flow/trunk/src/java/org/apache/struts/flow/portlet/Portlet.java (added)
+++ struts/flow/trunk/src/java/org/apache/struts/flow/portlet/Portlet.java Sat Nov 26 23:10:08 2005
@@ -0,0 +1,98 @@
+/*
+ *  Copyright 1999-2004 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.struts.flow.portlet;
+
+import org.apache.struts.flow.core.*;
+import javax.portlet.*;
+import org.apache.commons.chain.Context;
+import org.apache.commons.chain.web.portlet.PortletWebContext;
+
+import java.util.Map;
+
+/**
+ *  Access to Portlet resources
+ *
+ * @jsname portlet
+ */
+public class Portlet {
+    
+    protected PortletWebContext ctx = null;
+    protected static final Logger logger = Factory.getLogger();
+
+    public Portlet() {
+        throw new IllegalStateException("Cannot create new Struts object in a flow script");
+    }
+            
+
+    /**  Constructor for the JSLog object */
+    public Portlet(Context ctx) {
+        if (ctx instanceof PortletWebContext) {
+            this.ctx = (PortletWebContext)ctx;
+        } else {
+            logger.warn("Unknown context instance");
+        }
+    }
+    
+    /**
+     *  Gets a map of request parameters as Strings
+     */
+    public Map getParam() {
+        return ctx.getParam();
+    }
+    
+    /**
+     *  Gets a map of request parameters as String arrays
+     */
+    public Map getParamValues() {
+        return ctx.getParamValues();
+    }
+    
+    /**
+     *  Gets a map of request attributes
+     */
+    public Map getRequestScope() {
+        return ctx.getRequestScope();
+    }
+    
+    /**
+     *  Gets a map of session attributes
+     */
+    public Map getSessionScope() {
+        return ctx.getSessionScope();
+    }
+    
+    /**
+     *  Gets a map of application attributes
+     */
+    public Map getApplicationScope() {
+        return ctx.getApplicationScope();
+    }
+    
+    /**
+     *  Gets the portlet request
+     */
+    public PortletRequest getRequest() {
+        return ctx.getRequest();
+    }
+    
+    /**
+     *  Gets the portlet context
+     */
+    public PortletContext getPortletContext() {
+        return ctx.getContext();
+    }
+}
+

Propchange: struts/flow/trunk/src/java/org/apache/struts/flow/portlet/Portlet.java
------------------------------------------------------------------------------
    svn:executable = *



---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@struts.apache.org
For additional commands, e-mail: dev-help@struts.apache.org