/* ====================================================================
 * The Apache Software License, Version 1.1
 *
 * Copyright (c) 2000-2001 The Apache Software Foundation.  All rights
 * reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *
 * 3. The end-user documentation included with the redistribution,
 *    if any, must include the following acknowledgment:
 *       "This product includes software developed by the
 *        Apache Software Foundation (http://www.apache.org/)."
 *    Alternately, this acknowledgment may appear in the software itself,
 *    if and wherever such third-party acknowledgments normally appear.
 *
 * 4. The names "Apache" and "Apache Software Foundation" and
 *     "Apache Jetspeed" must not be used to endorse or promote products
 *    derived from this software without prior written permission. For
 *    written permission, please contact apache@apache.org.
 *
 * 5. Products derived from this software may not be called "Apache" or
 *    "Apache Jetspeed", nor may "Apache" appear in their name, without
 *    prior written permission of the Apache Software Foundation.
 *
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 * ====================================================================
 *
 * This software consists of voluntary contributions made by many
 * individuals on behalf of the Apache Software Foundation.  For more
 * information on the Apache Software Foundation, please see
 * <http://www.apache.org/>.
 */

package org.apache.jetspeed.portal.portlets;

import org.apache.jetspeed.portal.Portlet;
import org.apache.jetspeed.portal.PortletException;
import org.apache.jetspeed.portal.PortletConfig;
import org.apache.jetspeed.om.profile.ProfileLocator;
import org.apache.jetspeed.services.Profiler;
import org.apache.jetspeed.om.profile.Profile;
import org.apache.jetspeed.om.profile.PSMLDocument;
import org.apache.jetspeed.om.profile.Portlets;
import org.apache.jetspeed.services.rundata.JetspeedRunData;

import org.apache.jetspeed.services.persistence.PersistenceManager;
import org.apache.jetspeed.services.persistence.PortalPersistenceException;
import org.apache.jetspeed.portal.PortletInstance;

import org.apache.jetspeed.util.MimeType;

import org.apache.jetspeed.util.JetspeedClearElement;
import org.apache.ecs.ConcreteElement;

import org.apache.turbine.util.RunData;
import org.apache.turbine.util.Log;

import java.util.Locale;

/**
    Aggregate Portlet aggregates the content of other portlets.

    This portlet is a test for an alternate aggregation algorithm

    UNDER CONSTRUCTION

    @author <A HREF="mailto:taylor@apache.org">David Sean Taylor</A>
    @version $Id: ContainerTestPortlet.java,v 1.6 2003/03/04 00:05:04 sgala Exp $
*/

public class ContainerTestPortlet implements Portlet /* , PortletState, Cacheable, Refreshable */
{
    private String image = null;

    private String name = "not set";

    private String title = "la title";

    private String description = "description";

    private String id = null;

    private String handle = "";

    private PortletConfig   pc = null;


   /**
    Holds instances of ConcreteElements (Portlet output/content)
    based on its current CapabilityMap.
    */
    // protected Hashtable content = new Hashtable();

    /**
    The time this portlet was created.
    */
    private long creationTime;

    /**
    Returns a name for this portlet.  This is used by PSML to identify a Portlet
    within the PortletRegistry
    */
    public String getName()
    {
        return name;
    }

    /**
    Sets the name on this Portlet.

    @see #getName()
    */
    public void setName(String name)
    {
        System.out.println("setting name = " + name);
        this.name = name;
    }

    /**
    <p>
    Allows a Portlet to define its title.  This can be used by a PortletControl
    for rendering its content.
    </p>

    <p>
    In order to define a default title you should not override this but should
    call setTitle() within your init() method
    </p>

    <p>
    This should return null if not specified.
    </p>
    */
    public String getTitle()
    {
        return this.title;
    }

    public String getTitle(Locale locale)
    {
        return this.title;
    }

    /**
     * t a title for this instance of the portlet.  This method is called
     * from the context variable portlet_instance and from PortletInstance
     *
     * If you wish to append to the title, then you code should look like
     *    getTitle( String instanceTitle)
     *    {
     *      return super.getTitle( instanceTitle) + " - Appened title text";
     *    }
     *
     * @param instanceTitle Title from PSML
     */
    public String getTitle(String instanceTitle)
    {
        if (instanceTitle != null)
            return instanceTitle;
        return getTitle();
    }

    public String getTitle(String instanceTitle, Locale locale)
    {
        return getTitle(instanceTitle);
    }

    /**
    Set the title for this Portlet
    */
    public void setTitle( String title )
    {
        this.title = title;
    }

    /**
    <p>
    Returns a description of this portlet.  This should describe what the
    capabilities of the portlet and how it can help the user.
    </p>

    <p>
    In order to define a default title you should not override (in the
    AbstractPortlet implementation) this but should call setDescription()
    within your init() method
    </p>

    <p>
    This should return null if not specified.
    </p>
    */
    public String getDescription()
    {
        return description;
    }

    /**
     * Provide a Description within PML if the user has specified one.
     *
     * @return a null entry if the user hasn't defined anything
     */
    public String getDescription(String instanceDescription)
    {
      if (instanceDescription != null)
          return instanceDescription;
      return getDescription();
    }

    /**
    Set the description for this Portlet
    */
    public void setDescription( String description )
    {
        this.description = description;
    }

    /**
     * Getter for property image.
     * @return Name of portlet image, icon.  The name is expected to be in the form of a URL.
     */
    public String getImage()
    {
        return image;
    }

    /**
     * Getter for property image.
     * @return Name of portlet image, icon.  The name is expected to be in the form of a URL.
     */
    public String getImage(String instanceImage)
    {
      if (instanceImage != null)
          return instanceImage;
      return getImage();
    }

    public void setImage( String image )
    {
        this.image = image;
    }

    /**
    Returns an HTML representation of this portlet.  Usually a Portlet would
    initialized itself within init() and then when getContent is called it
    would return its presentation.
    */
    public ConcreteElement getContent(RunData rundata)
    {
        String key = ((JetspeedRunData)rundata).getProfile().getId()
                    + "." + this.getID();

        String path = (String)rundata.getUser().getTemp(key);
        if (path == null)
        {
            path = this.getPortletConfig().getInitParameter("path");
        }

        if (null == path)
        {
            return new JetspeedClearElement("Path parameter not set");
        }

        ProfileLocator locator = Profiler.createLocator();
        locator.createFromPath(path);
        String id = locator.getId();

        try
        {
            Profile profile = Profiler.getProfile(locator);
            PSMLDocument doc = profile.getDocument();
            if (doc == null)
            {
                return null;
            }
            Portlets portlets = doc.getPortlets();
            //PortletContainer.aggregate(portlets);
            return new JetspeedClearElement("XXX Under Construction :)");
        }
        catch (Exception e)
        {
            Log.error( e );
            return new JetspeedClearElement("Error in aggregation portlet: " + e.toString());
        }
    }

    /**
    All initialization should be performed here.  If your Portlet wants to
    do any work it should be done here.  You are not guaranteed that any
    particular order of method call will happen just that init() will happen
    first. Therefore if you have to calculate things like a title, a
    description, etc it should happen here.
    */
    public void init() throws PortletException
    {
        String path = this.pc.getInitParameter("path");
    }


    /**
    Set's the configuration of this servlet.
    */
    public void setPortletConfig(PortletConfig pc)
    {
        this.pc = pc;
    }


    /**
    Get the config of this servlet.
    */
    public PortletConfig getPortletConfig()
    {
        return pc;
    }

    /**
    <p>Return true if this portlet is allowed to be edited in the rundata's context .</p>

    <p>Note:  PortletControl implementations should pay attention to this so
    that they don't allow this option if it returns false.</p>
    */
    public boolean getAllowEdit( RunData rundata )
    {
        return false;
    }

    /**
    <p>Return true if this portlets is allowed to be maximized.</p>

    <p>Note:  PortletControl implementations should pay attention to this so
    that they don't allow this option if it returns false.</p>
    */
    public boolean getAllowMaximize( RunData rundata )
    {
        return true;
    }

    /**
    Get the creation time for this Portlet
    */
    public long getCreationTime()
    {

        return this.creationTime;
    }

    /**
    Set the creation time for this Portlet
    */
    public void setCreationTime( long creationTime )
    {
        System.out.println("setting creating time");
        this.creationTime = creationTime;
    }

    /**
    Returns true portlet is able to output content for given mimetype
    */
    public boolean supportsType( MimeType mimeType )
    {
        return true;
    }

   /**
     * Retrieve a portlet attribute from persistent storage
     *
     * @param attrName The attribute to retrieve
     * @param attrDefValue The value if the attr doesn't exists
     * @param rundata The RunData object for the current request
     * @return The attribute value
     */
    public String getAttribute( String attrName, String attrDefValue, RunData rundata )
    {
        String attrValue = null ;

        PortletInstance instance = PersistenceManager.getInstance(this, rundata);
        attrValue = instance.getAttribute(attrName, attrDefValue);

        return attrValue;
    }

    /**
     * Stores a portlet attribute in persistent storage
     *
     * @param attrName The attribute to retrieve
     * @paarm attrValue The value to store
     * @param rundata The RunData object for the current request
     */
    public void setAttribute( String attrName, String attrValue, RunData rundata )
    {
        try
        {
            PortletInstance instance = PersistenceManager.getInstance(this, rundata);
            instance.setAttribute(attrName, attrValue);
            PersistenceManager.store(instance);
        }
        catch (PortalPersistenceException e)
        {
            Log.error("Exception while setting attribute "+attrName+" for portlet "+getName(),e);
        }
    }

    /**
     * Gets the portlet instance associated with this portlet.
     *
     * @return PortletInstance
     */
    public PortletInstance getInstance(RunData rundata)
    {
       return PersistenceManager.getInstance(this, rundata);
    }




    /**
    Retrieve a unique portlet id
    */
    public String getID()
    {
        return "9";
    }

    public void setID(String id)
    {
        this.id = id;
    }

    /**
    * @return true if the portlet does its own customization
    */
    public boolean providesCustomization()
    {
        return false;
    }

    /** Returns TRUE if the title bar in should be displayed. The title bar includes
     * the portlet title and action buttons.  This
     *
     * @param rundata The RunData object for the current request
     */
    public boolean isShowTitleBar(RunData rundata)
    {
        return true;
    }


}
