/*******************************************************************************
 * Copyright (c) 2001, 2006 IBM Corporation and others.
 * 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:
 * IBM Corporation - initial API and implementation
 *******************************************************************************/
package org.eclipse.jst.j2ee.commonarchivecore.internal.impl;



import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.eclipse.emf.common.notify.Notification;
import org.eclipse.emf.common.notify.NotificationChain;
import org.eclipse.emf.common.notify.Notifier;
import org.eclipse.emf.common.notify.impl.AdapterImpl;
import org.eclipse.emf.common.util.EList;
import org.eclipse.emf.ecore.EClass;
import org.eclipse.emf.ecore.InternalEObject;
import org.eclipse.emf.ecore.util.EObjectContainmentWithInverseEList;
import org.eclipse.emf.ecore.util.InternalEList;
import org.eclipse.jst.j2ee.commonarchivecore.internal.CommonarchivePackage;
import org.eclipse.jst.j2ee.commonarchivecore.internal.Container;
import org.eclipse.jst.j2ee.commonarchivecore.internal.File;
import org.eclipse.jst.j2ee.commonarchivecore.internal.strategy.LoadStrategy;
import org.eclipse.jst.j2ee.commonarchivecore.internal.util.ArchiveUtil;


/**
 * @generated
 */
public abstract class ContainerImpl extends FileImpl implements Container {


	/**
	 * Inner class which maintains the index for the domain's collection of nodes keyed by name.
	 */
	protected class FileNotificationAdapter extends AdapterImpl {
		@Override
		public boolean isAdapterForType(Object type) {
			return (type == "FileNotificationAdapter");//$NON-NLS-1$
		}

		public void addIndexedFile(String newValue, Notifier notifier) {
			fileIndex.put(newValue, notifier);
			if (notifier.eAdapters() == null || !notifier.eAdapters().contains(this))
				notifier.eAdapters().add(this);
		}

		public void removeIndexedFile(String oldValue, Notifier notifier) {
			fileIndex.remove(oldValue);
			notifier.eAdapters().remove(this);
		}

		@Override
		public void notifyChanged(Notification notification) {
			if (fileIndex == null || notification.getFeature() == null)
				return;
			//If the name changed, update the index
			if (notification.getFeature().equals(CommonarchivePackage.eINSTANCE.getFile_URI()) && ((File) notification.getNotifier()).getContainer() == ContainerImpl.this) {
				fileIndex.remove(notification.getOldValue());
				fileIndex.put(notification.getNewValue(), notification.getNotifier());
			}
			//Handle adds and removes
			if (notification.getFeature().equals(CommonarchivePackage.eINSTANCE.getContainer_Files()) && notification.getNotifier() == ContainerImpl.this) {
				switch (notification.getEventType()) {
					case Notification.ADD : {
						File file = (File) notification.getNewValue();
						addIndexedFile(file.getURI(), file);
						break;
					}
					case Notification.REMOVE : {
						removeIndexedFile(((File) notification.getOldValue()).getURI(), (File) notification.getOldValue());
						break;
					}
					case Notification.ADD_MANY : {
						filesAdded((List) notification.getNewValue());
						break;
					}
					case Notification.REMOVE_MANY : {
						filesRemoved((List) notification.getOldValue());
						break;
					}
					case Notification.MOVE : {
						break;
					}
					case Notification.SET : {
						if (notification.getPosition() != Notification.NO_INDEX) { //This is now a
																				   // replace in
																				   // MOF2
							File file = (File) notification.getNewValue();
							removeIndexedFile(((File) notification.getOldValue()).getURI(), (File) notification.getOldValue());
							addIndexedFile(file.getURI(), file);
						}
						break;
					}
				}
			}
		}

		public void filesAdded(List newFiles) {
			for (int i = 0; i < newFiles.size(); i++) {
				File file = (File) newFiles.get(i);
				addIndexedFile(file.getURI(), file);
			}
		}

		public void filesRemoved(List oldFiles) {
			for (int i = 0; i < oldFiles.size(); i++) {
				File file = (File) oldFiles.get(i);
				removeIndexedFile(file.getURI(), file);
			}
		}

		public void rebuildFileIndex() {
			removeAdaptersIfNecessary();
			fileIndex = new HashMap();

			// If the primary collection already has elements,
			//'reflect them in the index...
			if (getFiles().size() > 0) {
				Iterator i = getFiles().iterator();
				while (i.hasNext()) {
					File file = (File) i.next();
					addIndexedFile(file.getURI(), file);
				}
			}
		}

		public void removeAdaptersIfNecessary() {
			if (fileIndex == null)
				return;
			Iterator iter = fileIndex.values().iterator();
			while (iter.hasNext()) {
				File aFile = (File) iter.next();
				aFile.eAdapters().remove(this);
			}
		}
	}

	/** Implementer for loading entries in this container */
	protected LoadStrategy loadStrategy;
	/**
	 * Index to provide fast lookup by name of files.
	 */
	protected Map fileIndex;
	/**
	 * An adapter which maintains the file index
	 */
	protected FileNotificationAdapter fileIndexAdapter;
	/**
	 * @generated This field/method will be replaced during code generation.
	 */
	/**
	 * @generated This field/method will be replaced during code generation.
	 */
	protected EList files = null;

	public ContainerImpl() {
		super();
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	protected EClass eStaticClass() {
		return CommonarchivePackage.Literals.CONTAINER;
	}

	/**
	 * @see com.ibm.etools.commonarchive.Archive
	 */
	public boolean containsFile(java.lang.String aUri) {
		String key = aUri.startsWith("/") ? ArchiveUtil.truncateFromFrontIgnoreCase(aUri, "/") : aUri;//$NON-NLS-2$//$NON-NLS-1$
		if (isIndexed())
			return getFileIndex().containsKey(key);
		return getLoadStrategy().contains(key);

	}

	/**
	 * @see com.ibm.etools.commonarchive.Container
	 */
	public java.lang.String getAbsolutePath() throws java.io.FileNotFoundException {
		return getLoadStrategy().getAbsolutePath();
	}

	public File getFile(String URI) throws java.io.FileNotFoundException {
		if (!isIndexed()) {
			getFiles();
		}
		File file = (File) getFileIndex().get(URI);
		if (file == null) {
			throw new java.io.FileNotFoundException(URI);
		}
		return file;
	}

	/**
	 * Insert the method's description here. Creation date: (12/05/00 7:20:21 PM)
	 * 
	 * @return java.util.Map
	 */
	protected java.util.Map getFileIndex() {
		if (fileIndex == null)
			getFileIndexAdapter().rebuildFileIndex();
		return fileIndex;
	}

	/**
	 * Insert the method's description here. Creation date: (12/05/00 7:20:21 PM)
	 * 
	 * @return FileNotificationAdapter
	 */
	protected FileNotificationAdapter getFileIndexAdapter() {
		if (fileIndexAdapter == null) {
			fileIndexAdapter = new FileNotificationAdapter();
			eAdapters().add(fileIndexAdapter);
		}
		return fileIndexAdapter;
	}

	/**
	 * List is built on demand, by requesting from the load strategy.
	 */
	public EList getFiles() {
		EList filesList = this.getFilesGen();
		if (!isIndexed()) {
			if (filesList.isEmpty() && getLoadStrategy() != null) {
				filesList.addAll(getLoadStrategy().collectFiles());
			}
			//Causes the index to be built
			getFileIndex();
		}
		return filesList;
	}

	/**
	 * @see com.ibm.etools.commonarchive.Archive Looks for a file with the given uri, and returns an
	 *      input stream; optimization: if the file list has not been built, goes directly to the
	 *      loadStrategy.
	 */
	public java.io.InputStream getInputStream(java.lang.String aUri) throws java.io.IOException, java.io.FileNotFoundException {
		if (isIndexed()) {
			return getFile(aUri).getInputStream();
		}
		return primGetInputStream(aUri);
	}

	/**
	 * Insert the method's description here. Creation date: (11/29/00 6:35:08 PM)
	 * 
	 * @return com.ibm.etools.archive.LoadStrategy
	 */
	public org.eclipse.jst.j2ee.commonarchivecore.internal.strategy.LoadStrategy getLoadStrategy() {
		return loadStrategy;
	}

	@Override
	public boolean isContainer() {
		return true;
	}

	public boolean isIndexed() {
		return fileIndex != null;
	}

	/**
	 * @see com.ibm.etools.commonarchive.Archive Goes directly to the loadStrategy.
	 */
	public java.io.InputStream primGetInputStream(java.lang.String aUri) throws java.io.IOException, java.io.FileNotFoundException {
		return getLoadStrategy().getInputStream(aUri);
	}

	public void rebuildFileIndex() {
		getFileIndexAdapter().rebuildFileIndex();
	}

	/**
	 * Insert the method's description here. Creation date: (11/29/00 6:35:08 PM)
	 * 
	 * @param newLoadStrategy
	 *            com.ibm.etools.archive.LoadStrategy
	 */
	public void setLoadStrategy(org.eclipse.jst.j2ee.commonarchivecore.internal.strategy.LoadStrategy newLoadStrategy) {

		if (newLoadStrategy != null) {
			newLoadStrategy.setContainer(this);
			if (loadStrategy != null) {
				newLoadStrategy.setRendererType(loadStrategy.getRendererType());
				newLoadStrategy.setReadOnly(loadStrategy.isReadOnly());
				loadStrategy.setContainer(null);
				loadStrategy.close();
			}
		}
		loadStrategy = newLoadStrategy;
	}

	/**
	 * @generated This field/method will be replaced during code generation
	 */
	public EList getFilesGen() {
		if (files == null) {
			files = new EObjectContainmentWithInverseEList(File.class, this, CommonarchivePackage.CONTAINER__FILES, CommonarchivePackage.FILE__CONTAINER);
		}
		return files;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public NotificationChain eInverseAdd(InternalEObject otherEnd, int featureID, NotificationChain msgs) {
		switch (featureID) {
			case CommonarchivePackage.CONTAINER__FILES:
				return ((InternalEList)getFiles()).basicAdd(otherEnd, msgs);
		}
		return super.eInverseAdd(otherEnd, featureID, msgs);
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public NotificationChain eInverseRemove(InternalEObject otherEnd, int featureID, NotificationChain msgs) {
		switch (featureID) {
			case CommonarchivePackage.CONTAINER__FILES:
				return ((InternalEList)getFiles()).basicRemove(otherEnd, msgs);
		}
		return super.eInverseRemove(otherEnd, featureID, msgs);
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public Object eGet(int featureID, boolean resolve, boolean coreType) {
		switch (featureID) {
			case CommonarchivePackage.CONTAINER__FILES:
				return getFiles();
		}
		return super.eGet(featureID, resolve, coreType);
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public void eSet(int featureID, Object newValue) {
		switch (featureID) {
			case CommonarchivePackage.CONTAINER__FILES:
				getFiles().clear();
				getFiles().addAll((Collection)newValue);
				return;
		}
		super.eSet(featureID, newValue);
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public void eUnset(int featureID) {
		switch (featureID) {
			case CommonarchivePackage.CONTAINER__FILES:
				getFiles().clear();
				return;
		}
		super.eUnset(featureID);
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public boolean eIsSet(int featureID) {
		switch (featureID) {
			case CommonarchivePackage.CONTAINER__FILES:
				return files != null && !files.isEmpty();
		}
		return super.eIsSet(featureID);
	}

	public void clearFiles() {
		boolean oldDelivery = eDeliver();
		files.clear();
		eSetDeliver(oldDelivery);
		if (isIndexed()) {
			eAdapters().remove(fileIndexAdapter);
			fileIndexAdapter = null;
			fileIndex = null;
		}
	}
}
