//  Copyright 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.tapestry;

import java.io.IOException;
import java.util.Locale;

import javax.servlet.ServletException;

import org.apache.tapestry.asset.ResourceChecksumSource;
import org.apache.tapestry.engine.IComponentClassEnhancer;
import org.apache.tapestry.engine.IComponentMessagesSource;
import org.apache.tapestry.engine.IEngineService;
import org.apache.tapestry.engine.IPageRecorder;
import org.apache.tapestry.engine.IPageSource;
import org.apache.tapestry.engine.IPropertySource;
import org.apache.tapestry.engine.IScriptSource;
import org.apache.tapestry.engine.ISpecificationSource;
import org.apache.tapestry.engine.ITemplateSource;
import org.apache.tapestry.request.RequestContext;
import org.apache.tapestry.spec.IApplicationSpecification;
import org.apache.tapestry.util.io.DataSqueezer;
import org.apache.tapestry.util.pool.Pool;

/**
 * Defines the core, session-persistant object used to run a Tapestry
 * application for a single client (each client will have its own instance of the engine).
 *
 * <p>The engine exists to provide core services to the pages and components
 * that make up the application.  The engine is a delegate to the
 * {@link ApplicationServlet} via the {@link #service(RequestContext)} method.
 *
 * <p>Engine instances are persisted in the {@link javax.servlet.http.HttpSession} and are serializable.
 *
 * @author Howard Lewis Ship
 * @version $Id$
 **/

public interface IEngine
{
    /**
     *  The name ("Home") of the default page presented when a user first accesses the
     *  application.
     *
     *  @see org.apache.tapestry.engine.HomeService
     * 
     **/

    public static final String HOME_PAGE = "Home";

    /**
     *  The name ("Exception") of the page used for reporting exceptions.
     *  
     *  <p>Such a page must have
     *  a writable JavaBeans property named 'exception' of type 
     * <code>java.lang.Throwable</code>.
     *
     **/

    public static final String EXCEPTION_PAGE = "Exception";

    /**
     *  The name ("StaleLink") of the page used for reporting stale links.
     *
     *  <p>The page must implement a writeable JavaBeans proeprty named
     *  'message' of type <code>String</code>.
     *
     **/ 

    public static final String STALE_LINK_PAGE = "StaleLink";
    
    /**
     *  Returns a recorder for a page.  Returns null if the page recorder has
     *  not been created yet.
     *
     *  @see #createPageRecorder(String, IRequestCycle)
     * 
     **/

    public IPageRecorder getPageRecorder(String pageName, IRequestCycle cycle);

    /**
     *  The name ("StaleSession") of the page used for reporting state sessions.
     *
     **/

    public static final String STALE_SESSION_PAGE = "StaleSession";

    /**
     *  Forgets changes to the named page by discarding the page recorder for the page.
     *  This is used when transitioning from one part
     *  of an application to another.  All property changes for the page are lost.
     *
     *  <p>This should be done if the page is no longer needed or relevant, otherwise
     *  the properties for the page will continue to be recorded by the engine, which
     *  is wasteful (especially if clustering or failover is employed on the application).
     *
     *  <p>Throws an {@link ApplicationRuntimeException} if there are uncommitted changes
     *  for the recorder (in the current request cycle).
     *
     **/

    public void forgetPage(String name);

    /**
     *  Returns the locale for the engine.  This locale is used when selecting
     *  templates and assets.
     **/

    public Locale getLocale();

    /**
     *  Changes the engine's locale.  Any subsequently loaded pages will be
     *  in the new locale (though pages already loaded stay in the old locale).
     *  Generally, you should render a new page after changing the locale, to
     *  show that the locale has changed.
     *
     **/

    public void setLocale(Locale value);



    /**
     *  Creates a new page recorder for the named page.
     *
     **/

    public IPageRecorder createPageRecorder(String pageName, IRequestCycle cycle);

    /**
     *  Returns the object used to load a page from its specification.
     *
     **/

    public IPageSource getPageSource();

    /**
     *  Gets the named service, or throws an {@link
     *  org.apache.tapestry.ApplicationRuntimeException} 
     *  if the application can't provide
     *  the named server.
     *
     *  <p>The object returned has a short lifecycle (it isn't
     *  serialized with the engine).  Repeated calls with the
     *  same name are not guarenteed to return the same object,
     *  especially in different request cycles.
     *
     **/

    public IEngineService getService(String name);

    /**
     *  Returns the URL path that corresponds to the servlet for the application.  
     *  This is required by instances of {@link IEngineService} that need 
     *  to construct URLs for the application.  This value will include
     *  the context path.
     **/

    public String getServletPath();

    /**
     *  Returns the context path, a string which is prepended to the names of
     *  any assets or servlets.  This may be the empty string, but won't be null.
     *
     *  <p>This value is obtained from 
     *  {@link javax.servlet.http.HttpServletRequest#getContextPath()}.
     * 
     **/

    public String getContextPath();

    /**
     *  Returns the application specification that defines the application
     *  and its pages.
     *
     **/

    public IApplicationSpecification getSpecification();

    /**
     *  Returns the source of all component specifications for the application.  
     *  The source is shared between sessions.
     *
     *  @see org.apache.tapestry.engine.AbstractEngine#createSpecificationSource(RequestContext)
     * 
     **/

    public ISpecificationSource getSpecificationSource();

    /**
     *  Returns the source for HTML templates.
     *
     *  @see  org.apache.tapestry.engine.AbstractEngine#createTemplateSource(RequestContext)
     * 
     **/

    public ITemplateSource getTemplateSource();

    /**
     *  Method invoked from the {@link org.apache.tapestry.ApplicationServlet} 
     *  to perform processing of the
     *  request.  In release 3.0, this has become more of a dirty flag, indicating
     *  if any state stored by the engine instance itself has changed.
     *
     *  @return true if the state of the engine was, or could have been, changed during
     *  processing.
     *
     **/

    public boolean service(RequestContext context) throws ServletException, IOException;

    /**
     *  Returns an object that can resolve resources and classes.
     *
     **/

    public IResourceResolver getResourceResolver();

    /**
     *  Returns the visit object, an object that represents the client's visit
     *  to the application.  This is where most server-side state is stored (with
     *  the exception of persistent page properties).
     *
     *  <p>Returns the visit, if it exists, or null if it has not been created.
     *
     **/

    public Object getVisit();

    /**
     *  Returns the visit object, creating it if necessary.
     *
     **/

    public Object getVisit(IRequestCycle cycle);

    /**
     *  Allows the visit object to be removed; typically done when "shutting down"
     *  a user's session (by setting the visit to null).
     *
     **/

    public void setVisit(Object value);

    /**
     *  Returns the globally shared application object. The global object is
     *  stored in the servlet context and shared by all instances of the engine
     *  for the same application (within the same JVM; the global is
     *  <em>not</em> shared between nodes in a cluster).
     *
     *  <p>Returns the global object, if it exists, or null if not defined.
     *
     *  @since 2.3
     * 
     **/

    public Object getGlobal();

    /**
     *  Returns true if the application allows the reset service.
     *
     *  @since 0.2.9
     * 
     **/

    public boolean isResetServiceEnabled();

    /**
     *  Returns a source for parsed 
     *  {@link org.apache.tapestry.IScript}s.  The source is 
     *  shared between all sessions.
     *
     *  @since 1.0.2
     *
     **/

    public IScriptSource getScriptSource();

    /**
     *  Returns true if the engine has state and, therefore, should be stored
     *  in the HttpSession.  This starts as false, but becomes true when
     *  the engine requires state (such as when a visit object is created,
     *  or when a peristent page property is set).
     *
     *  @since 1.0.2
     *
     **/

    public boolean isStateful();

	/**
	 *  Returns a shared object that allows components to find
	 *  their set of localized strings.
	 * 
	 *  @since 2.0.4
	 * 
     *  @see org.apache.tapestry.engine.AbstractEngine#createComponentStringsSource(RequestContext)
     * 
	 **/
	
	public IComponentMessagesSource getComponentMessagesSource();

    /**
     *  Returns a shared instance of {@link org.apache.tapestry.util.io.DataSqueezer}.
     * 
     *  @since 2.2
     * 
     *  @see org.apache.tapestry.engine.AbstractEngine#createDataSqueezer()
     * 
     **/
    
    public DataSqueezer getDataSqueezer();

    /**
     *  Returns a {@link org.apache.tapestry.engine.IPropertySource} that should be
     *  used to obtain configuration data.  The returned source represents
     *  a search path that includes (at a minimum):
     *  
     *  <ul>
     *  <li>Properties of the {@link org.apache.tapestry.spec.ApplicationSpecification}
     *  <li>Initial Parameters of servlet (configured in the <code>web.xml</code> deployment descriptor)
     *  <li>Initial Parameter of the servlet context (also configured in <code>web.xml</code>)
     *  <li>System properties (defined with the <code>-D</code> JVM command line parameter)
     *  <li>Hard-coded "factory defaults" (for some properties)
     *  </ul>
     * 
     *  @since 2.3
     *  @see org.apache.tapestry.engine.AbstractEngine#createPropertySource(RequestContext)
     * 
     **/

    public IPropertySource getPropertySource();
    
    /**
     *  Returns a {@link org.apache.tapestry.util.pool.Pool} that is used
     *  to store all manner of objects that are needed throughout the system.
     *  This is the best way to deal with objects that are both expensive to
     *  create and not threadsafe.  The reset service
     *  will clear out this Pool.
     * 
     *  @since 3.0
     *  @see org.apache.tapestry.engine.AbstractEngine#createPool(RequestContext)
     * 
     **/
    
    public Pool getPool();
    
    /**
     *  Returns an object that can create enhanced versions of component classes.
     * 
     *  @since 3.0
     *  @see org.apache.tapestry.engine.AbstractEngine#createComponentClassEnhancer(RequestContext)
     * 
     **/
    
    public IComponentClassEnhancer getComponentClassEnhancer();
    
    /**
     *  Returns the encoding to be used to generate the servlet responses and 
     *  accept the servlet requests.
     * 
     *  @since 3.0
     * 
     **/
    
    public String getOutputEncoding();
    
    /**
     * Returns an object that can compute the checksum of a resource.
     * @since 3.0.3
     */
    public ResourceChecksumSource getResourceChecksumSource();
}
