tikhomirov@148: /* tikhomirov@148: * Copyright (c) 2011 TMate Software Ltd tikhomirov@148: * tikhomirov@148: * This program is free software; you can redistribute it and/or modify tikhomirov@148: * it under the terms of the GNU General Public License as published by tikhomirov@148: * the Free Software Foundation; version 2 of the License. tikhomirov@148: * tikhomirov@148: * This program is distributed in the hope that it will be useful, tikhomirov@148: * but WITHOUT ANY WARRANTY; without even the implied warranty of tikhomirov@148: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the tikhomirov@148: * GNU General Public License for more details. tikhomirov@148: * tikhomirov@148: * For information on how to redistribute this software under tikhomirov@148: * the terms of a license other than GNU General Public License tikhomirov@148: * contact TMate Software at support@hg4j.com tikhomirov@148: */ tikhomirov@148: package org.tmatesoft.hg.util; tikhomirov@148: tikhomirov@148: /** tikhomirov@148: * Extension mechanism. tikhomirov@148: * tikhomirov@148: * @author Artem Tikhomirov tikhomirov@148: * @author TMate Software Ltd. tikhomirov@148: */ tikhomirov@148: public interface Adaptable { tikhomirov@148: tikhomirov@148: T getAdapter(Class adapterClass); tikhomirov@356: tikhomirov@356: class Factory { tikhomirov@356: tikhomirov@356: private final Class adapterClass; tikhomirov@356: tikhomirov@356: public Factory(Class adapterClass) { tikhomirov@356: assert adapterClass != null; tikhomirov@356: this.adapterClass = adapterClass; tikhomirov@356: } tikhomirov@356: tikhomirov@356: public T get(Object target) { tikhomirov@356: return getAdapter(target, adapterClass, null); tikhomirov@356: } tikhomirov@356: tikhomirov@356: public T get(Object target, T defaultValue) { tikhomirov@356: return getAdapter(target, adapterClass, defaultValue); tikhomirov@356: } tikhomirov@356: tikhomirov@356: /** tikhomirov@356: * Try to adapt target to specified class, resort to defaultValue when not possible. tikhomirov@356: * Instance lookup order is as follows: first, target is checked for being {@link Adaptable} and, if yes, tikhomirov@356: * consulted for adapter. Then, plain {@link Class#isInstance(Object) instanceof} checks if target itself is tikhomirov@356: * of desired type. {@link Adaptable} check comes first to allow classed that are in fact instanceof tikhomirov@356: * desired type to respond to the demand conditionally tikhomirov@356: * tikhomirov@356: * @param target object to adapt, null value, although meaningless, is tolerable. tikhomirov@356: * @param adapterClass desired target class tikhomirov@356: * @param defaultValue value to use if target cannot be adapted to desired class, may be null tikhomirov@356: * @return instance of the desired class tikhomirov@356: */ tikhomirov@356: public static C getAdapter(Object target, Class adapterClass, C defaultValue) { tikhomirov@356: if (target instanceof Adaptable) { tikhomirov@356: return ((Adaptable) target).getAdapter(adapterClass); tikhomirov@356: } tikhomirov@356: if (adapterClass.isInstance(target)) { tikhomirov@356: return adapterClass.cast(target); tikhomirov@356: } tikhomirov@356: return defaultValue; tikhomirov@356: } tikhomirov@356: } tikhomirov@148: }