//  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: IEngine.java 244167 2005-03-17 08:14:54Z pferraro $
 **/

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();
}
