/*******************************************************************************
 * Copyright (c) 2007, 2010 Oracle. All rights reserved.
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Public License v1.0, which accompanies this distribution
 * and is available at http://www.eclipse.org/legal/epl-v10.html.
 * 
 * Contributors:
 *     Oracle - initial API and implementation
 ******************************************************************************/
package org.eclipse.jpt.jpa.core.resource.xml;

import java.io.IOException;
import java.util.Collections;

import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.content.IContentType;
import org.eclipse.emf.common.notify.Adapter;
import org.eclipse.emf.common.notify.Notification;
import org.eclipse.emf.common.util.EList;
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.jem.util.emf.workbench.WorkbenchResourceHelperBase;
import org.eclipse.jem.util.plugin.JEMUtilPlugin;
import org.eclipse.jpt.common.core.JptResourceModel;
import org.eclipse.jpt.common.core.JptResourceModelListener;
import org.eclipse.jpt.common.core.JptResourceType;
import org.eclipse.jpt.common.utility.internal.ListenerList;
import org.eclipse.jpt.common.utility.internal.StringTools;
import org.eclipse.jpt.jpa.core.JptJpaCorePlugin;
import org.eclipse.jst.j2ee.internal.xml.J2EEXmlDtDEntityResolver;
import org.eclipse.wst.common.internal.emf.resource.Renderer;
import org.eclipse.wst.common.internal.emf.resource.Translator;
import org.eclipse.wst.common.internal.emf.resource.TranslatorResourceImpl;
import org.xml.sax.EntityResolver;

/**
 * Provisional API: This interface is part of an interim API that is still
 * under development and expected to change significantly before reaching
 * stability. It is available at this early stage to solicit feedback from
 * pioneering adopters on the understanding that any code that uses this API
 * will almost certainly be broken (repeatedly) as the API evolves.
 * 
 * @version 2.3
 * @since 2.2
 */
public class JpaXmlResource
	extends TranslatorResourceImpl
	implements JptResourceModel
{
	/**
	 * cache the content type - if the content type changes, the JPA project
	 * will throw out the JPA file holding the xml resource and build a new one
	 */
	protected final IContentType contentType;
	
	protected final Translator rootTranslator;
	
	protected final ListenerList<JptResourceModelListener> resourceModelListenerList =
			new ListenerList<JptResourceModelListener>(JptResourceModelListener.class);
	
	
	public JpaXmlResource(URI uri, Renderer renderer, IContentType contentType, Translator rootTranslator) {
		super(uri, renderer);
		this.contentType = contentType;
		this.rootTranslator = rootTranslator;
	}
	
	public IContentType getContentType() {
		return this.contentType;
	}
	
	public String getVersion() {
		JpaRootEObject root = this.getRootObject();
		return (root == null) ? null : root.getVersion();
	}

	/**
	 * Build a new resource type every time(?).
	 */
	public JptResourceType getResourceType() {
		String version = this.getVersion();
		return ((this.contentType == null) || (version == null)) ?
			null :
			new JptResourceType(this.contentType, version);
	}
	
	
	// ********** BasicNotifierImpl override **********
	
	/**
	 * Override to fire notification only when:<ul>
	 * <li>the resource's state has actually changed; and
	 * <li>the resource is loaded; and
	 * <li>the resource's resource set is still present (EMF will fire an
	 *    notification when the resource set is set to 'null', just before
	 *    the resource is "unloaded" - we want to swallow this notification)
	 * </ul>
	 */
	@Override
	public void eNotify(Notification notification) {
		// unload events can happen before the resource set is removed - should always react to unload events
		if (this.loadedFlagCleared(notification)) {
			super.eNotify(notification);
			if (this.isReverting()) {
				this.resourceModelReverted();
			} else {
				this.resourceModelUnloaded();
			}
		}
		else if ( ! notification.isTouch() && this.isLoaded() && (this.resourceSet != null)) {
			super.eNotify(notification);
			this.resourceModelChanged();
		}
	}
	
	/**
	 * Return whether the specified notification indicates the resource has been
	 * unloaded.
	 * we could use this method to suppress some notifications; or we could just
	 * check whether 'resourceSet' is 'null' (which is what we do)
	 */
	protected boolean loadedFlagCleared(Notification notification) {
		return (notification.getNotifier() == this) &&
				(notification.getEventType() == Notification.SET) &&
				(notification.getFeatureID(Resource.class) == RESOURCE__IS_LOADED) &&
				( ! notification.getNewBooleanValue());
	}
	
	/**
	 * Return whether the specified notification indicates the resource's
	 * resource set was cleared.
	 * We could use this method to suppress some resource set notifications;
	 * or we could just check whether <code>resourceSet</code> is
	 * <code>null</code> (which is what we do)/
	 */
	protected boolean resultSetCleared(Notification notification) {
		return (notification.getNotifier() == this) &&
				(notification.getEventType() == Notification.SET) &&
				(notification.getFeatureID(Resource.class) == RESOURCE__RESOURCE_SET) &&
				(notification.getNewValue() == null);
	}
	
	
	// ********** TranslatorResource implementation **********
	
	/**
	 * only applicable for DTD-based files
	 */
	public String getDoctype() {
		return null;
	}
	
	public Translator getRootTranslator() {
		return this.rootTranslator;
	}
	
	
	// ********** TranslatorResourceImpl implementation **********
	
	/**
	 * only applicable for DTD-based files
	 */
	@Override
	protected String getDefaultPublicId() {
		return null;
	}
	
	/**
	 * only applicable for DTD-based files
	 */
	@Override
	protected String getDefaultSystemId() {
		return null;
	}
	
	/**
	 * this seems to be the default version of the spec for this doc
	 * and the id 10 maps to the version 1.0
	 */
	@Override
	protected int getDefaultVersionID() {
		return 10;
	}
	
	@Override
	public JpaRootEObject getRootObject() {
		EObject root = super.getRootObject();
		try {
			return (JpaRootEObject) root;
		} catch (ClassCastException ex) {
			throw new IllegalStateException("The root object of a JPA XML resource must implement JpaRootEObject: " + root, ex); //$NON-NLS-1$
		}
	}
	
	//296544 - override this to avoid internet access finding the schema during tests
	@Override
	public EntityResolver getEntityResolver() {
		return J2EEXmlDtDEntityResolver.INSTANCE;
	}
	
	
	// ********** convenience methods **********
	
	public boolean fileExists() {
		return this.getFile().exists();
	}
	
	public IFile getFile() {
		IFile file = this.getFile(this.uri);
		return (file != null) ? file : this.getConvertedURIFile();
	}
	
	protected IFile getConvertedURIFile() {
		if (this.resourceSet == null) {
			return null;
		}
		URI convertedURI = this.resourceSet.getURIConverter().normalize(this.uri);
		return this.uri.equals(convertedURI) ? null : this.getFile(convertedURI);
	}
	
	/**
	 * Return the Eclipse file for the specified URI.
	 * This URI is assumed to be absolute in the following format:
	 *     platform:/resource/....
	 */
	protected IFile getFile(URI fileURI) {
		if ( ! WorkbenchResourceHelperBase.isPlatformResourceURI(fileURI)) {
			return null;
		}
		String fileName = URI.decode(fileURI.path()).substring(JEMUtilPlugin.PLATFORM_RESOURCE.length() + 1);
		return ResourcesPlugin.getWorkspace().getRoot().getFile(new Path(fileName));
	}
	
	public IProject getProject() {
		return this.getFile().getProject();
	}
	
	public void modify(Runnable runnable) {
		try {
			runnable.run();
			try {
				save(Collections.EMPTY_MAP);
			} catch (IOException ex) {
				JptJpaCorePlugin.log(ex);
			}
		} catch (Exception ex) {
			JptJpaCorePlugin.log(ex);
		}
	}
	
	@Override
	public String toString() {
		// implementation in TranslatorResourceImpl is a bit off...
		return StringTools.buildToStringFor(this, this.getURI());
	}
	
	
	// ********** JptResourceModel implementation **********
	
	public void addResourceModelListener(JptResourceModelListener listener) {
		this.resourceModelListenerList.add(listener);
	}
	
	public void removeResourceModelListener(JptResourceModelListener listener) {
		this.resourceModelListenerList.remove(listener);
	}


	// ********** listener notifications **********

	protected void resourceModelChanged() {
		for (JptResourceModelListener listener : this.resourceModelListenerList.getListeners()) {
			listener.resourceModelChanged(this);
		}
	}

	protected void resourceModelReverted() {
		for (JptResourceModelListener listener : this.resourceModelListenerList.getListeners()) {
			listener.resourceModelReverted(this);
		}
	}

	protected void resourceModelUnloaded() {
		for (JptResourceModelListener listener : this.resourceModelListenerList.getListeners()) {
			listener.resourceModelUnloaded(this);
		}
	}


	// ********** cast things back to what they are in EMF **********

	@SuppressWarnings("unchecked")
	@Override
	public EList<Adapter> eAdapters() {
		return super.eAdapters();
	}
	
	@SuppressWarnings("unchecked")
	@Override
	public EList<EObject> getContents() {
		return super.getContents();
	}
}
