/******************************************************************************* * Copyright (c) 2011 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.equinox.bidi.advanced; import java.util.HashMap; import java.util.Map; import org.eclipse.equinox.bidi.StructuredTextProcessor; import org.eclipse.equinox.bidi.StructuredTextTypeHandlerFactory; import org.eclipse.equinox.bidi.custom.StructuredTextTypeHandler; import org.eclipse.equinox.bidi.internal.StructuredTextImpl; /** * Obtains IStructuredTextExpert instances. * An {@link IStructuredTextExpert} instance (called in short an "expert") provides * the advanced methods to process a certain type of structured text, and * is thus related to a specific * {@link StructuredTextTypeHandler structured text type handler}. * There are two kinds of experts: * <ul> * <li>stateful, obtained by calling {@link #getStatefulExpert}.</li> * <li>not stateful, obtained by calling {@link #getExpert}.</li> * </ul> * <p>Only the stateful kind can remember the state established by a call to * a text processing method and transmit it as initial state in the next call * to a text processing method. * <p>In other words, the methods * {@link IStructuredTextExpert#getState()}, * {@link IStructuredTextExpert#setState} and * {@link IStructuredTextExpert#clearState()} of * {@link IStructuredTextExpert} are inoperative for experts which are not stateful. * <p> * Using a stateful expert is more resource intensive, thus not stateful * experts should be used when feasible. */ final public class StructuredTextExpertFactory { /** * The default set of separators used to segment a string: dot, colon, slash, backslash. */ private static final String defaultSeparators = StructuredTextProcessor.getDefaultSeparators(); static private Map sharedDefaultExperts = new HashMap(); // String type -> expert static private Map sharedExperts = new HashMap(); // String type -> map of { environment -> expert } static private IStructuredTextExpert defaultExpert; private StructuredTextExpertFactory() { // prevents instantiation } /** * Obtains a IStructuredTextExpert instance for processing structured text with * a default type handler segmenting the text according to default separators. * This expert instance does not handle states. * @return the IStructuredTextExpert instance. * @see StructuredTextProcessor#getDefaultSeparators() */ static public IStructuredTextExpert getExpert() { if (defaultExpert == null) { StructuredTextTypeHandler handler = new StructuredTextTypeHandler(defaultSeparators); defaultExpert = new StructuredTextImpl(handler, StructuredTextEnvironment.DEFAULT, false); } return defaultExpert; } /** * Obtains a IStructuredTextExpert instance for processing structured text with * the specified type handler. * This expert instance does not handle states. * * @param type the identifier for the required type handler. This identifier * may be one of those listed in {@link StructuredTextTypeHandlerFactory} * or it may be have been registered by a plug-in. * @return the IStructuredTextExpert instance. * @throws IllegalArgumentException if <code>type</code> is not a known type * identifier. */ static public IStructuredTextExpert getExpert(String type) { IStructuredTextExpert expert; synchronized (sharedDefaultExperts) { expert = (IStructuredTextExpert) sharedDefaultExperts.get(type); if (expert == null) { StructuredTextTypeHandler handler = StructuredTextTypeHandlerFactory.getHandler(type); if (handler == null) throw new IllegalArgumentException("Invalid type argument"); //$NON-NLS-1$ expert = new StructuredTextImpl(handler, StructuredTextEnvironment.DEFAULT, false); sharedDefaultExperts.put(type, expert); } } return expert; } /** * Obtains a IStructuredTextExpert instance for processing structured text with * the specified type handler and the specified environment. * This expert instance does not handle states. * * @param type the identifier for the required type handler. This identifier * may be one of those listed in {@link StructuredTextTypeHandlerFactory} * or it may be have been registered by a plug-in. * @param environment the current environment, which may affect the behavior of * the expert. This parameter may be specified as * <code>null</code>, in which case the * {@link StructuredTextEnvironment#DEFAULT} * environment should be assumed. * @return the IStructuredTextExpert instance. * @throws IllegalArgumentException if <code>type</code> is not a known type * identifier. */ static public IStructuredTextExpert getExpert(String type, StructuredTextEnvironment environment) { IStructuredTextExpert expert; if (environment == null) environment = StructuredTextEnvironment.DEFAULT; synchronized (sharedExperts) { Map experts = (Map) sharedExperts.get(type); if (experts == null) { experts = new HashMap(); // environment -> expert sharedExperts.put(type, experts); } expert = (IStructuredTextExpert) experts.get(environment); if (expert == null) { StructuredTextTypeHandler handler = StructuredTextTypeHandlerFactory.getHandler(type); if (handler == null) throw new IllegalArgumentException("Invalid type argument"); //$NON-NLS-1$ expert = new StructuredTextImpl(handler, environment, false); experts.put(type, expert); } } return expert; } /** * Obtains a IStructuredTextExpert instance for processing structured text with * the specified type handler. * This expert instance can handle states. * * @param type the identifier for the required type handler. This identifier * may be one of those listed in {@link StructuredTextTypeHandlerFactory} * or it may be have been registered by a plug-in. * @return the IStructuredTextExpert instance. * @throws IllegalArgumentException if <code>type</code> is not a known type * identifier. */ static public IStructuredTextExpert getStatefulExpert(String type) { return getStatefulExpert(type, StructuredTextEnvironment.DEFAULT); } /** * Obtains a IStructuredTextExpert instance for processing structured text with * the specified type handler and the specified environment. * This expert instance can handle states. * * @param type the identifier for the required type handler. This identifier * may be one of those listed in {@link StructuredTextTypeHandlerFactory} * or it may be have been registered by a plug-in. * @param environment the current environment, which may affect the behavior of * the expert. This parameter may be specified as * <code>null</code>, in which case the * {@link StructuredTextEnvironment#DEFAULT} * environment should be assumed. * @return the IStructuredTextExpert instance. * @throws IllegalArgumentException if <code>type</code> is not a known type * identifier. */ static public IStructuredTextExpert getStatefulExpert(String type, StructuredTextEnvironment environment) { StructuredTextTypeHandler handler = StructuredTextTypeHandlerFactory.getHandler(type); if (handler == null) throw new IllegalArgumentException("Invalid type argument"); //$NON-NLS-1$ return getStatefulExpert(handler, environment); } /** * Obtains a IStructuredTextExpert instance for processing structured text with * the specified type handler and the specified environment. * This expert instance can handle states. * * @param handler the type handler instance. It may have been obtained using * {@link StructuredTextTypeHandlerFactory#getHandler(String)} or * by instantiating a type handler. * @param environment the current environment, which may affect the behavior of * the expert. This parameter may be specified as * <code>null</code>, in which case the * {@link StructuredTextEnvironment#DEFAULT} * environment should be assumed. * @return the IStructuredTextExpert instance * @throws IllegalArgumentException if the <code>handler</code> is <code>null</code> */ static public IStructuredTextExpert getStatefulExpert(StructuredTextTypeHandler handler, StructuredTextEnvironment environment) { if (handler == null) throw new IllegalArgumentException("handler must not be null"); //$NON-NLS-1$ if (environment == null) environment = StructuredTextEnvironment.DEFAULT; return new StructuredTextImpl(handler, environment, true); } }