/*
 * The contents of this file are subject to the terms 
 * of the Common Development and Distribution License 
 * (the License).  You may not use this file except in
 * compliance with the License.
 * 
 * You can obtain a copy of the license at 
 * https://glassfish.dev.java.net/public/CDDLv1.0.html or
 * glassfish/bootstrap/legal/CDDLv1.0.txt.
 * See the License for the specific language governing 
 * permissions and limitations under the License.
 * 
 * When distributing Covered Code, include this CDDL 
 * Header Notice in each file and include the License file 
 * at glassfish/bootstrap/legal/CDDLv1.0.txt.  
 * If applicable, add the following below the CDDL Header, 
 * with the fields enclosed by brackets [] replaced by
 * you own identifying information: 
 * "Portions Copyrighted [year] [name of copyright owner]"
 * 
 * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
 */

package com.sun.enterprise.tools.admingui.descriptors;

import com.iplanet.jato.ModelManager;
import com.iplanet.jato.RequestManager;
import com.iplanet.jato.RequestContext;
import com.iplanet.jato.view.ContainerView;
import com.iplanet.jato.view.ContainerViewBase;
import com.iplanet.jato.view.View;
import com.sun.web.ui.model.CCManageChildrenModel;

import com.sun.enterprise.tools.guiframework.exception.FrameworkException;
import com.sun.enterprise.tools.guiframework.view.descriptors.ViewDescriptor;
import com.sun.enterprise.tools.guiframework.view.descriptors.FakeContainerDescriptor;
import com.sun.enterprise.tools.guiframework.util.LogUtil;

import com.sun.enterprise.tools.admingui.taglib.DataSheet;
import com.sun.enterprise.tools.admingui.taglib.DataSheetModelInterface;

import java.io.InputStream;
import java.net.URL;

import org.xml.sax.EntityResolver;
import org.xml.sax.InputSource;


/**
 *
 */
public class DataSheetDescriptor extends ViewDescriptor implements FakeContainerDescriptor {

    /**
     *	Constructor
     */
    public DataSheetDescriptor(String name) {
	super(name);
    }


    public void registerChildren(ContainerViewBase instance) {
	// Invoke the super registerChild
        super.registerChildren(instance);

	getModel().registerChildren(instance);
    }
    

    /**
     *	This method creates empty descriptors on the fly for fields that are
     *	defined by the underlying model.
     */
    public ViewDescriptor getChildDescriptor(String name) {
    	// Do the normal stuff if we can...
	ViewDescriptor desc = super.getChildDescriptor(name);
	if (desc != null) {
	    return desc;
	}

	// Do we need to create a descriptor on the fly?
	DataSheetModelInterface model = getModel();
        if (model != null && model.isChildSupported(name)) {
	    // YES
	    desc = new DataSheetChildDescriptor(name);
	    // NOTE: This call is safe (mostly), because although we are
	    // NOTE: modifying a static structure... this change is applicable
	    // NOTE: to all users.  However, there is a slight possibility of
	    // NOTE: of a sync. problem... not worth worrying about now.  If
	    // NOTE: this does become a problem, just remove the
	    // NOTE: addChildDescriptor() line below.
	    addChildDescriptor(desc);
	    return desc;
	}

	return null;
    }

    class myEntityResolver implements EntityResolver { 
        public InputSource resolveEntity (String publicId, String systemId) {

            if (systemId != null && (systemId.startsWith("http")==false) && 
                (systemId.endsWith(".xml") || systemId.endsWith(".dtd"))) {
                InputStream resourceStream = null;
                int i = systemId.indexOf("dtd/");
                if (i >= 0) {
                    systemId = "xml/" + systemId.substring(i);
                    //System.out.println("systemID: " + systemId);
                    // First look in the classpath, the file maybe in a JAR
                    resourceStream = getClass().getClassLoader()
                        .getResourceAsStream(systemId);
                    if (resourceStream == null) {
                        // Next look in the app directory.
                        String sURL = "file:///" + 
                            RequestManager.getRequestContext().getServletContext()
                            .getRealPath(systemId);
                        //System.out.println("sURL: " + sURL);
                        try {
                            resourceStream = new URL(sURL).openStream();
                        } catch (Exception ex) {
                            //System.out.println(":::::::::::"+ex.getMessage());
                        }
                    }
                }
                if (resourceStream != null) {
                    return new InputSource(resourceStream);
                }
            }
            // use the default behaviour
            return null;
        }
    }
    
    /**
     *	<P>This method will get the CCPropertySheetModel for this property
     *	sheet.  If one has not already been created, it will create a new one.
     *	This method depends on the "XML_FILE" property being defined.  You must
     *	also have a model mapping entry in the "ModelTypeMap" for
     *	"DataSheetModelInterface.class".</P>
     *
     *	<P>Optionally, you may specify whether this model should be retrieved
     *	and/or stored from/in session.  The GET_FROM_SESSION and
     *	STORE_IN_SESSION parameters control this.</P>
     */
    public DataSheetModelInterface getModel() {
	// Determine if the session should be used w/ the model manager.
	boolean fromSession = shouldGetModelFromSession();
	boolean toSession = shouldPutModelToSession();
	String instanceName = getModelInstanceName();

	// Use the ModelManager to create/get the model
	ModelManager mgr = RequestManager.getRequestContext().getModelManager();
	DataSheetModelInterface model =
	    (DataSheetModelInterface)mgr.getModel(
                DataSheetModelInterface.class,
		instanceName, fromSession, toSession);

	// Make sure the XML file is set on the Model
	if (model.getDocument() == null) {
	    InputStream in = getXMLFileAsStream();
            model.setEntityResolver(new DataSheetDescriptor.myEntityResolver());
//            String resolverName  = null;
//            EntityResolver er = null;
//            try {
//                resolverName = (String)this.getParameter("EntityResolverClassName");
//                if (resolverName != null && model instanceof CCManageChildrenModel) {
//                    er = (EntityResolver) Class.forName(resolverName).newInstance();
//                    model.setEntityResolver(er);
//                }
//            } catch (Exception ex) {
//                if (LogUtil.isLoggable(LogUtil.WARNING)) {
//                    LogUtil.log(LogUtil.WARNING, resolverName+": "+ex.getMessage());
//                }
//            }
	    model.setDocument(in);
	    try {
		in.close();
	    } catch (java.io.IOException ex) {
		// Ignore
	    }
        }
	return model;
    }


    /**
     *	This is a factory method for CCActionTable instances.
     *
     *	@param	ctx	The RequestContext
     *	@param	container	The container for the newly created 
     */
    public View getInstance(RequestContext ctx, ContainerView container, String name) {
	return new DescriptorDataSheet(ctx, container, name, this, getModel());
    }
}
