package org.semanticweb.elk.reasoner.indexing.model;

/*
 * #%L
 * ELK Reasoner
 * $Id:$
 * $HeadURL:$
 * %%
 * Copyright (C) 2011 - 2015 Department of Computer Science, University of Oxford
 * %%
 * 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.
 * #L%
 */

/**
 * A {@link ModifiableIndexedObjectHasSelf} that can be used for memoization
 * (caching).
 * 
 * @author "Yevgeny Kazakov"
 */
public interface CachedIndexedObjectHasSelf extends
		ModifiableIndexedObjectHasSelf,
		CachedIndexedComplexClassExpression<CachedIndexedObjectHasSelf> {

	/**
	 * A factory for creating instances
	 * 
	 * @author Yevgeny Kazakov
	 *
	 */
	interface Factory {

		CachedIndexedObjectHasSelf getIndexedObjectHasSelf(
				ModifiableIndexedObjectProperty property);

	}
	
	/**
	 * A filter for mapping objects
	 * 
	 * @author Yevgeny Kazakov
	 *
	 */
	interface Filter {

		CachedIndexedObjectHasSelf filter(CachedIndexedObjectHasSelf element);

	}
	
	static class Helper extends CachedIndexedObject.Helper {

		public static int structuralHashCode(IndexedObjectProperty property) {
			return combinedHashCode(CachedIndexedObjectHasSelf.class, property);
		}

		public static CachedIndexedObjectHasSelf structuralEquals(
				CachedIndexedObjectHasSelf first, Object second) {
			if (first == second) {
				return first;
			}
			if (second instanceof CachedIndexedObjectHasSelf) {
				CachedIndexedObjectHasSelf secondEntry = (CachedIndexedObjectHasSelf) second;
				if (first.getProperty().equals(secondEntry.getProperty()))
					return secondEntry;
			}
			// else
			return null;
		}

	}

}
