/** * Reports the GeoTools {@linkplain #getVersion version} number to the {@linkplain System#out * standard output stream}. * * @param args Command line arguments. */ public static void main(String[] args) { final Arguments arguments = new Arguments(args); args = arguments.getRemainingArguments(0); arguments.out.print("GeoTools version "); arguments.out.println(getVersion()); final Hints hints = getDefaultHints(); if (hints != null && !hints.isEmpty()) { arguments.out.println(hints); } }
@Override public void draw() { camera.update(); batch.setProjectionMatrix(camera.combined); batch.begin(); if (isHinting) hint.drawBack(batch); snappers.draw(); blasts.draw(); // bangs.draw(); if (isHinting) hint.draw(batch); batch.end(); }
@Override public void act(float delta) { int acts = logic.advance2(delta); super.act(delta); boolean isGameOver = logic.isGameOver(); if (isGameOver && !gameOverFired) { if (logic.isGameLost()) { gameOverFired = true; mGame.gameLost(); } else { if (timeToFireWon > 0) timeToFireWon -= delta; else { gameOverFired = true; mGame.gameWon(); } } } else if (!isGameOver && gameOverFired) { gameOverFired = false; timeToFireWon = TIME_TO_WAIT_FOR_WON; } sounds.act(delta, acts); // bangs.act(delta); snappers.act(delta); if (isHinting) hint.act(delta); if (isTutorialAvailable && !isHinting && !areSnappersTouched() && (System.currentTimeMillis() - logic.startTime) > WAIT_FOR_TUTORIAL) showHints(true); }
@Override public void tap() { mGame.getAppListener().updateTapsLeft(logic.tapRemains); if (isHinting) { if (logic.tapRemains > 0) hint.hintTapped(); else isHinting = false; } }
/** * Creates a new proxy for the given key. * * @throws NotSerializableException If the given key is not declared as a static constant in its * {@linkplain Class#getEnclosingClass() enclosing class}. */ SerializedKey(final RenderingHints.Key key) throws NotSerializableException { final Field f = Hints.fieldOf(key); if (f == null) { throw new NotSerializableException( Errors.format(Errors.Keys.UnknownType_1, Classes.getShortClassName(key))); } definer = f.getDeclaringClass(); field = f.getName(); }
public void showHints(boolean showText) { if (isHinting) return; if (areSnappersTouched()) restartLevel(); if (hint == null) hint = new Hints(logic); else hint.updateLevel(); logic.hintUsed = true; isHinting = true; }
/** * Scans {@linkplain System#getProperties system properties} for any property keys defined in this * class, and add their values to the specified map of hints. For example if the {@value * #FORCE_LONGITUDE_FIRST_AXIS_ORDER} system property is defined, then the {@link * Hints#FORCE_LONGITUDE_FIRST_AXIS_ORDER FORCE_LONGITUDE_FIRST_AXIS_ORDER} hint will be added to * the set of hints. * * @return {@code true} if at least one hint changed as a result of this scan, or {@code false} * otherwise. */ static boolean scanForSystemHints(final Hints hints) { assert Thread.holdsLock(hints); boolean changed = false; synchronized (BINDINGS) { for (final Map.Entry<String, RenderingHints.Key> entry : BINDINGS.entrySet()) { final String propertyKey = entry.getKey(); final String property; try { property = System.getProperty(propertyKey); } catch (SecurityException e) { unexpectedException(e); continue; } if (property != null) { /* * Converts the system property value from String to Object (java.lang.Boolean * or java.lang.Number). We perform this conversion only if the key is exactly * of kind Hints.Key, not a subclass like ClassKey, in order to avoid useless * class loading on 'getValueClass()' method invocation (ClassKey don't make * sense for Boolean and Number, which are the only types that we convert here). */ Object value = property; final RenderingHints.Key hintKey = entry.getValue(); if (hintKey.getClass().equals(Hints.Key.class)) { final Class<?> type = ((Hints.Key) hintKey).getValueClass(); if (type.equals(Boolean.class)) { value = Boolean.valueOf(property); } else if (Number.class.isAssignableFrom(type)) try { value = Classes.valueOf(type, property); } catch (NumberFormatException e) { unexpectedException(e); continue; } } final Object old; try { old = hints.put(hintKey, value); } catch (IllegalArgumentException e) { // The property value is illegal for this hint. unexpectedException(e); continue; } if (!changed && !Utilities.equals(old, value)) { changed = true; } } } } return changed; }
@Test(expectedExceptions = IllegalArgumentException.class) public void mergeWithShouldFailWithExceptionIfOtherLinksToDifferentResource() { // given final TemplatedLink aboutPageLink = ABOUTPAGE_LINK; final TemplatedLink otherTemplatedLink = templatedLink( RESOURCELINK_SHOP_PAGE, "/foo/{fooId}", asList(hrefVar("fooId", VAR_TYPE_PAGEID, emptyDocs())), Hints.hints(of(GET), asList("text/html"))); // when aboutPageLink.mergeWith(otherTemplatedLink); // then an exception is thrown }
@Test(expectedExceptions = IllegalArgumentException.class) public void mergeWithShouldFailWithExceptionIfOtherDoesNotHaveSameRelationType() { // given final TemplatedLink aboutPageLink = ABOUTPAGE_LINK; final TemplatedLink otherTemplatedLink = TemplatedLink.templatedLink( RESOURCELINK_SHOP_STOREFRONT, REL_PAGE_HREF, asList(hrefVar("pageId", VAR_TYPE_PAGEID, emptyDocs())), Hints.hints(of(GET), asList("text/html"))); // when aboutPageLink.mergeWith(otherTemplatedLink); // then an exception is thrown }
@Test(expectedExceptions = IllegalArgumentException.class) public void mergeWithShouldFailForDifferentHrefVars() { // given final TemplatedLink aboutPageLink = ABOUTPAGE_LINK; final TemplatedLink otherTemplatedLink = templatedLink( RESOURCELINK_SHOP_PAGE, "pages/{pageId}", asList(hrefVar("foo", VAR_TYPE_PAGEID)), Hints.hints(of(GET), asList("text/html", "application/json"))); // when aboutPageLink.mergeWith(otherTemplatedLink); // then an exception is thrown }
@Test public void mergeWithShouldMergeAllowsSpec() { // given final TemplatedLink aboutPageLink = ABOUTPAGE_LINK; final TemplatedLink otherTemplatedLink = templatedLink( RESOURCELINK_SHOP_PAGE, REL_PAGE_HREF, asList(hrefVar("pageId", VAR_TYPE_PAGEID, emptyDocs())), Hints.hints(of(PUT), asList("text/html", "application/json"))); // when final ResourceLink resourceLink = aboutPageLink.mergeWith(otherTemplatedLink); // then assertEquals(resourceLink.getHints().getAllows(), of(GET, PUT)); }
@Test(enabled = false) public void mergeWithShouldMergeAcceptPost() { // given final TemplatedLink thisTemplatedLink = templatedLink( RESOURCELINK_SHOP_PAGE, REL_PAGE_HREF, asList(hrefVar("pageId", VAR_TYPE_PAGEID)), Hints.hints( of(GET, POST), asList("application/foo"), Collections.<String>emptyList(), asList("application/json"), Collections.<Precondition>emptyList(), Status.OK, emptyDocs())); final TemplatedLink thatTemplatedLink = templatedLink( RESOURCELINK_SHOP_PAGE, REL_PAGE_HREF, asList(hrefVar("pageId", VAR_TYPE_PAGEID)), Hints.hints( of(GET, POST), asList("application/foo"), Collections.<String>emptyList(), asList("application/foo"), Collections.<Precondition>emptyList(), Status.OK, emptyDocs())); // when final ResourceLink resourceLink = thisTemplatedLink.mergeWith(thatTemplatedLink); // then final Hints hints = resourceLink.getHints(); assertEquals(hints.getRepresentations(), asList("application/foo")); assertEquals(hints.getAcceptPost(), asList("application/json", "application/foo")); }
/** * Initializes GeoTools for use. This convenience method performs various tasks (more may be added * in the future), including setting up the {@linkplain java.util.logging Java logging framework} * in one of the following states: * * <p> * * <ul> * <li>If the <A HREF="http://jakarta.apache.org/commons/logging/">Commons-logging</A> framework * is available, then every logging message in the {@code org.geotools} namespace sent to * the Java {@linkplain java.util.logging.Logger logger} are redirected to Commons-logging. * <li>Otherwise if the <A HREF="http://logging.apache.org/log4j">Log4J</A> framework is * available, then every logging message in the {@code org.geotools} namespace sent to the * Java {@linkplain java.util.logging.Logger logger} are redirected to Log4J. * <li>Otherwise, the Java logging {@linkplain java.util.logging.Formatter formatter} for * console output is replaced by a {@linkplain org.geotools.util.logging.MonolineFormatter * monoline formatter}. * </ul> * * <p>In addition, the {@linkplain #getDefaultHints default hints} are initialized to the * specified {@code hints}. * * <p>Note that invoking this method is usually <strong>not</strong> needed for proper working of * the Geotools library. It is just a convenience method for overwriting some Java and Geotools * default settings in a way that seems to be common in server environment. Such overwriting may * not be wanted for every situations. * * <p>Example of typical invocation in a Geoserver environment: * * <blockquote> * * <pre> * Hints hints = new Hints(); * hints.put({@linkplain Hints#FORCE_LONGITUDE_FIRST_AXIS_ORDER}, Boolean.TRUE); * hints.put({@linkplain Hints#FORCE_AXIS_ORDER_HONORING}, "http"); * GeoTools.init(hints); * </pre> * * </blockquote> * * @param hints The hints to use. * @see Logging#setLoggerFactory(String) * @see Logging#forceMonolineConsoleOutput * @see Hints#putSystemDefault * @see #getDefaultHints */ public static void init(final Hints hints) { final Logging log = Logging.GEOTOOLS; try { log.setLoggerFactory("org.geotools.util.logging.CommonsLoggerFactory"); } catch (ClassNotFoundException commonsException) { try { log.setLoggerFactory("org.geotools.util.logging.Log4JLoggerFactory"); } catch (ClassNotFoundException log4jException) { // Nothing to do, we already tried our best. } } // If java logging is used, force monoline console output. if (log.getLoggerFactory() == null) { log.forceMonolineConsoleOutput(); } if (hints != null) { Hints.putSystemDefault(hints); // fireConfigurationChanged() is invoked in the above method call. } }
/** * Returns {@code true} is the specified {@code factory} meets the requirements specified by a map * of {@code hints}. This method checks only the hints; it doesn't check the {@link Filter}, the * {@linkplain OptionalFactory#isAvailable availability} or the user-overrideable {@link * #isAcceptable(Object, Class, Hints)} method. This method invokes itself recursively. * * @param factory The factory to checks. * @param category The factory category. Usually an interface. * @param hints The user requirements ({@code null} not allowed). * @param alreadyDone Should be {@code null} except on recursive calls (for internal use only). * @return {@code true} if the {@code factory} meets the hints requirements. */ private boolean usesAcceptableHints( final Factory factory, final Class<?> category, final Hints hints, Set<Factory> alreadyDone) { /* * Ask for implementation hints with special care against infinite recursivity. * Some implementations use deferred algorithms fetching dependencies only when * first needed. The call to getImplementationHints() is sometime a trigger for * fetching dependencies (in order to return accurate hints). For example the * BufferedCoordinateOperationFactory implementation asks for an other instance * of CoordinateOperationFactory, the instance to cache behind a buffer, which * should not be itself. Of course BufferedCoordinateOperation will checks that * it is not caching itself, but its test happen too late for preventing a never- * ending loop if we don't put a 'testingHints' guard here. It is also a safety * against broken factory implementations. */ if (!testingHints.addAndCheck(factory)) { return false; } final Map<RenderingHints.Key, ?> implementationHints; try { implementationHints = Hints.stripNonKeys(factory.getImplementationHints()); } finally { testingHints.removeAndCheck(factory); } if (implementationHints == null) { // factory was bad and did not meet contract - assume it used no Hints return true; } /* * We got the implementation hints. Now tests their compatibility. */ Hints remaining = null; for (final Map.Entry<?, ?> entry : implementationHints.entrySet()) { final Object key = entry.getKey(); final Object value = entry.getValue(); final Object expected = hints.get(key); if (expected != null) { /* * We have found a hint that matter. Check if the * available factory meets the user's criterions. */ if (expected instanceof Class<?>) { if (!((Class<?>) expected).isInstance(value)) { return false; } } else if (expected instanceof Class<?>[]) { final Class<?>[] types = (Class<?>[]) expected; int i = 0; do if (i >= types.length) return false; while (!types[i++].isInstance(value)); } else if (!expected.equals(value)) { return false; } } /* * Checks recursively in factory dependencies, if any. Note that the dependencies * will be checked against a subset of user's hints. More specifically, all hints * processed by the current pass will NOT be passed to the factories dependencies. * This is because the same hint may appears in the "parent" factory and a "child" * dependency with different value. For example the FORCE_LONGITUDE_FIRST_AXIS_ORDER * hint has the value TRUE in OrderedAxisAuthorityFactory, but the later is basically * a wrapper around the ThreadedEpsgFactory (typically), which has the value FALSE * for the same hint. * * Additional note: The 'alreadyDone' set is a safety against cyclic dependencies, * in order to protect ourself against never-ending loops. This is not the same * kind of dependencies than 'testingHints'. It is a "factory A depends on factory * B which depends on factory A" loop, which is legal. */ if (value instanceof Factory) { final Factory dependency = (Factory) value; if (alreadyDone == null) { alreadyDone = new HashSet<Factory>(); } if (!alreadyDone.contains(dependency)) { alreadyDone.add(factory); if (remaining == null) { remaining = new Hints(hints); remaining.keySet().removeAll(implementationHints.keySet()); } final Class<?> type; if (key instanceof Hints.Key) { type = ((Hints.Key) key).getValueClass(); } else { type = Factory.class; // Kind of unknown factory type... } // Recursive call to this method for scanning dependencies. if (!usesAcceptableHints(dependency, type, remaining, alreadyDone)) { return false; } } } } return true; }
/** * Returns the first provider in the registry for the specified category, using the specified map * of hints (if any). This method may {@linkplain #scanForPlugins scan for plugins} the first time * it is invoked. Except as a result of this scan, no new provider instance is created by the * default implementation of this method. The {@link FactoryCreator} class change this behavior * however. * * @param <T> The class represented by the {@code category} argument. * @param category The category to look for. Must be one of the categories declared to the * constructor. Usually an interface class (not the actual implementation class). * @param filter An optional filter, or {@code null} if none. This is used for example in order to * select the first factory for some {@linkplain * org.opengis.referencing.AuthorityFactory#getAuthority authority}. * @param hints A {@linkplain Hints map of hints}, or {@code null} if none. * @param key The key to use for looking for a user-provided instance in the hints, or {@code * null} if none. * @return A factory {@linkplain OptionalFactory#isAvailable available} for use for the specified * category and hints. The returns type is {@code Object} instead of {@link Factory} because * the factory implementation doesn't need to be a Geotools one. * @throws FactoryNotFoundException if no factory was found for the specified category, filter and * hints. * @throws FactoryRegistryException if a factory can't be returned for some other reason. * @see #getServiceProviders(Class, Filter, Hints) * @see FactoryCreator#getServiceProvider */ public <T> T getServiceProvider( final Class<T> category, final Filter filter, Hints hints, final Hints.Key key) throws FactoryRegistryException { synchronizeIteratorProviders(); final boolean debug = LOGGER.isLoggable(DEBUG_LEVEL); if (debug) { /* * We are not required to insert the method name ("GetServiceProvider") in the * message because it is part of the informations already stored by LogRecord, * and formatted by the default java.util.logging.SimpleFormatter. * * Conventions for the message part according java.util.logging.Logger javadoc: * - "ENTRY" at the begining of a method. * - "RETURN" at the end of a method, if successful. * - "THROW" in case of failure. * - "CHECK" ... is our own addition to Sun's convention for this method ... */ debug("ENTRY", category, key, null, null); } Class<?> implementation = null; if (key != null) { /* * Sanity check: make sure that the key class is appropriate for the category. */ final Class<?> valueClass = key.getValueClass(); if (!category.isAssignableFrom(valueClass)) { if (debug) { debug("THROW", category, key, "unexpected type:", valueClass); } throw new IllegalArgumentException(Errors.format(ErrorKeys.ILLEGAL_KEY_$1, key)); } if (hints != null) { final Object hint = hints.get(key); if (hint != null) { if (debug) { debug("CHECK", category, key, "user provided a", hint.getClass()); } if (category.isInstance(hint)) { /* * The factory implementation was given explicitly by the user. * Nothing to do; we are done. */ if (debug) { debug("RETURN", category, key, "return hint as provided.", null); } return category.cast(hint); } /* * Before to pass the hints to the private 'getServiceImplementation' method, * remove the hint for the user-supplied key. This is because this hint has * been processed by this public 'getServiceProvider' method, and the policy * is to remove the processed hints before to pass them to child dependencies * (see the "Check recursively in factory dependencies" comment elswhere in * this class). * * Use case: DefaultDataSourceTest invokes indirectly 'getServiceProvider' * with a "CRS_AUTHORITY_FACTORY = ThreadedEpsgFactory.class" hint. However * ThreadedEpsgFactory (in the org.geotools.referencing.factory.epsg package) * is a wrapper around DirectEpsgFactory, and defines this dependency through * a "CRS_AUTHORITY_FACTORY = DirectEpsgFactory.class" hint. There is no way * to match this hint for both factories in same time. Since we must choose * one, we assume that the user is interrested in the most top level one and * discart this particular hint for the dependencies. */ hints = new Hints(hints); if (hints.remove(key) != hint) { // Should never happen except on concurrent modification in an other thread. throw new AssertionError(key); } /* * If the user accepts many implementation classes, then try all of them in * the preference order given by the user. The last class (or the singleton * if the hint was not an array) will be tried using the "normal" path * (oustide the loop) in order to get the error message in case of failure. */ if (hint instanceof Class<?>[]) { final Class<?>[] types = (Class<?>[]) hint; final int length = types.length; for (int i = 0; i < length - 1; i++) { final Class<?> type = types[i]; if (debug) { debug("CHECK", category, key, "consider hint[" + i + ']', type); } final T candidate = getServiceImplementation(category, type, filter, hints); if (candidate != null) { if (debug) { debug("RETURN", category, key, "found implementation", candidate.getClass()); } return candidate; } } if (length != 0) { implementation = types[length - 1]; // Last try to be done below. } } else { implementation = (Class<?>) hint; } } } } if (debug && implementation != null) { debug("CHECK", category, key, "consider hint[last]", implementation); } final T candidate = getServiceImplementation(category, implementation, filter, hints); if (candidate != null) { if (debug) { debug("RETURN", category, key, "found implementation", candidate.getClass()); } return candidate; } if (debug) { debug("THROW", category, key, "could not find implementation.", null); } throw new FactoryNotFoundException( Errors.format( ErrorKeys.FACTORY_NOT_FOUND_$1, implementation != null ? implementation : category)); }
@Override public boolean canTap(int i, int j) { return !isHinting || hint.isHintingSnapper(i, j); }
/** * Returns the default set of hints used for the various utility classes. This default set is * determined by: * * <p> * * <ul> * <li>The {@linplain System#getProperties system properties} available. Some property keys are * enumerated in the {@link GeoTools} class. * <li>Any hints added by call to the {@link Hints#putSystemDefault} or {@link #init} method. * </ul> * * <p><b>Long term plan:</b> We would like to transition the utility classes to being injected * with their required factories, either by taking Hints as part of their constructor, or * otherwise. Making this change would be a three step process 1) create instance methods for each * static final class method 2) create an singleton instance of the class 3) change each static * final class method into a call to the singleton. With this in place we could then encourage * client code to make use of utility class instances before eventually retiring the static final * methods. * * @return A copy of the default hints. It is safe to add to it. */ public static Hints getDefaultHints() { return Hints.getDefaults(false); }