org.wrml.runtime.syntax.DefaultSyntaxLoader.java Source code

Java tutorial

Introduction

Here is the source code for org.wrml.runtime.syntax.DefaultSyntaxLoader.java

Source

/**
 * WRML - Web Resource Modeling Language
 *  __     __   ______   __    __   __
 * /\ \  _ \ \ /\  == \ /\ "-./  \ /\ \
 * \ \ \/ ".\ \\ \  __< \ \ \-./\ \\ \ \____
 *  \ \__/".~\_\\ \_\ \_\\ \_\ \ \_\\ \_____\
 *   \/_/   \/_/ \/_/ /_/ \/_/  \/_/ \/_____/
 *
 * http://www.wrml.org
 *
 * Copyright (C) 2011 - 2013 Mark Masse <mark@wrml.org> (OSS project WRML.org)
 *
 * 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.
 */
package org.wrml.runtime.syntax;

import com.google.common.collect.BiMap;
import com.google.common.collect.HashBiMap;
import org.apache.commons.lang3.reflect.TypeUtils;
import org.wrml.model.schema.Syntax;
import org.wrml.runtime.Context;
import org.wrml.runtime.ContextConfiguration;
import org.wrml.runtime.Keys;

import java.lang.reflect.Type;
import java.net.URI;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

public final class DefaultSyntaxLoader implements SyntaxLoader {

    private final Map<URI, Syntax> _SystemSyntaxes;

    private final BiMap<URI, Class<?>> _SyntaxUriToJavaClassBiMap;

    private final ConcurrentHashMap<Class<?>, SyntaxHandler<?>> _SyntaxHandlers;

    private Context _Context;

    public DefaultSyntaxLoader() {

        _SystemSyntaxes = new HashMap<>();
        _SyntaxHandlers = new ConcurrentHashMap<>();
        _SyntaxUriToJavaClassBiMap = HashBiMap.create();
    }

    @Override
    @SuppressWarnings({ "rawtypes", "unchecked" })
    public final String formatSyntaxValue(final Object syntaxValue) {

        if (syntaxValue instanceof String) {
            return (String) syntaxValue;
        }

        if (syntaxValue == null) {
            return null;
        }

        final SyntaxHandler syntaxHandler = getSyntaxHandler(syntaxValue.getClass());

        if (syntaxHandler != null) {
            return syntaxHandler.formatSyntaxValue(syntaxValue);
        }

        return String.valueOf(syntaxValue);
    }

    @Override
    public Context getContext() {

        return _Context;
    }

    @Override
    @SuppressWarnings("unchecked")
    public final <T> SyntaxHandler<T> getSyntaxHandler(final Class<T> syntaxJavaClass) {

        return (SyntaxHandler<T>) _SyntaxHandlers.get(syntaxJavaClass);
    }

    @Override
    public final Class<?> getSyntaxJavaClass(final URI syntaxUri) {

        if (!_SyntaxUriToJavaClassBiMap.containsKey(syntaxUri)) {
            return null;
        }

        return _SyntaxUriToJavaClassBiMap.get(syntaxUri);
    }

    @Override
    public final URI getSyntaxUri(final Class<?> syntaxClass) {

        final BiMap<Class<?>, URI> javaClassToSyntaxUriMap = _SyntaxUriToJavaClassBiMap.inverse();
        if (!javaClassToSyntaxUriMap.containsKey(syntaxClass)) {
            return null;
        }

        return javaClassToSyntaxUriMap.get(syntaxClass);
    }

    @Override
    public void loadInitialState() {

        loadConfiguredSyntaxes();
    }

    @Override
    @SuppressWarnings({ "unchecked", "rawtypes" })
    public final <T> T parseSyntacticText(final String text, final java.lang.reflect.Type targetType) {

        if (text == null) {
            return null;
        }

        if (targetType == null || targetType.equals(String.class)) {
            return (T) text;
        }

        if (targetType.equals(Integer.TYPE) || targetType.equals(Integer.class)) {
            return (T) new Integer(text);
        }

        if (targetType.equals(Boolean.TYPE) || targetType.equals(Boolean.class)) {
            return (T) (text.equals("true") ? Boolean.TRUE : Boolean.FALSE);
        }

        if (targetType.equals(Long.TYPE) || targetType.equals(Long.class)) {
            return (T) new Long(text);
        }

        if (targetType.equals(Double.TYPE) || targetType.equals(Double.class)) {
            return (T) new Double(text);
        }

        if (TypeUtils.isAssignable(targetType, Enum.class)) {
            return (T) Enum.valueOf((Class<Enum>) targetType, text);
        }

        if (targetType instanceof Class<?>) {

            final SyntaxHandler<?> syntaxHandler = getSyntaxHandler((Class<?>) targetType);

            if (syntaxHandler != null) {
                return (T) syntaxHandler.parseSyntacticText(text);
            }
        }

        throw new SyntaxRegistryException(
                "Failed to transform text: \"" + text + "\" value to target type: " + targetType, null, this);

    }

    @Override
    public void init(final Context context) {

        _Context = context;
        loadSystemSyntaxes();

    }

    @Override
    @SuppressWarnings("unchecked")
    public final <T> T[] parseSyntacticTextArray(final String[] textArray, final T[] destArray) {

        final Type arrayComponentType = TypeUtils.getArrayComponentType(destArray.getClass());
        for (int i = 0; i < textArray.length; i++) {
            destArray[i] = (T) parseSyntacticText(textArray[i], arrayComponentType);
        }
        return destArray;
    }

    @Override
    public final void loadConfiguredSyntax(final SyntaxConfiguration syntaxConfiguration) {

        if (syntaxConfiguration == null) {
            return;
        }

        final URI syntaxUri = syntaxConfiguration.getSyntaxUri();
        if (syntaxUri == null) {
            throw new SyntaxRegistryException("The Syntax id (URI) cannot be null", null, this);
        }

        final String syntaxHandlerClassName = syntaxConfiguration.getHandler();
        if (syntaxHandlerClassName == null) {
            throw new SyntaxRegistryException("The SyntaxHandler class name cannot be null", null, this);
        }

        Class<?> syntaxHandlerClass;
        try {
            syntaxHandlerClass = Class.forName(syntaxHandlerClassName);
        } catch (final ClassNotFoundException e) {
            throw new SyntaxRegistryException("Failed to load SyntaxHandler class (" + syntaxHandlerClassName + ")",
                    e, this);
        }

        SyntaxHandler<?> syntaxHandler = null;
        try {
            syntaxHandler = (SyntaxHandler<?>) syntaxHandlerClass.newInstance();
        } catch (final Exception e) {
            throw new SyntaxRegistryException(
                    "Failed to create new instance of SyntaxHandler class (" + syntaxHandlerClass + ")", e, this);
        }

        loadSyntax(syntaxUri, syntaxHandler);

    }

    @Override
    public final void loadSyntax(final URI syntaxUri, final SyntaxHandler<?> syntaxHandler) {

        if (_SyntaxUriToJavaClassBiMap.containsKey(syntaxUri)) {
            throw new SyntaxRegistryException("The syntax  \"" + syntaxUri + "\" is already installed (using: "
                    + _SyntaxUriToJavaClassBiMap.get(syntaxUri) + ")", null, this);

        }

        final Class<?> syntaxJavaClass = syntaxHandler.getSyntaxType();
        if (_SyntaxHandlers.containsKey(syntaxJavaClass)) {
            throw new SyntaxRegistryException("The syntax  \"" + syntaxJavaClass.getCanonicalName()
                    + "\" is already installed (using: " + _SyntaxHandlers.get(syntaxJavaClass) + ")", null, this);

        }

        loadSyntaxInternal(syntaxUri, syntaxHandler);

    }

    @Override
    public Syntax getLoadedSyntax(final Keys keys) {

        final URI uri = keys.getValue(getContext().getSchemaLoader().getDocumentSchemaUri());
        if (uri == null) {
            return null;
        }

        if (_SystemSyntaxes.containsKey(uri)) {
            return _SystemSyntaxes.get(uri);
        }

        return null;
    }

    private final void loadSyntaxInternal(final URI syntaxUri, final SyntaxHandler<?> syntaxHandler) {

        final Class<?> syntaxJavaClass = syntaxHandler.getSyntaxType();
        _SyntaxUriToJavaClassBiMap.put(syntaxUri, syntaxJavaClass);
        _SyntaxHandlers.put(syntaxJavaClass, syntaxHandler);
    }

    private final void loadSystemSyntaxes() {

        for (final SystemSyntax systemSyntax : SystemSyntax.values()) {
            final SyntaxHandler<?> syntaxHandler = systemSyntax.getSyntaxHandler();

            switch (systemSyntax) {

            case Boolean:
                _SyntaxHandlers.put(Boolean.TYPE, syntaxHandler);
                break;

            case Double:
                _SyntaxHandlers.put(Double.TYPE, syntaxHandler);
                break;

            case Integer:
                _SyntaxHandlers.put(Integer.TYPE, syntaxHandler);
                break;

            case Long:
                _SyntaxHandlers.put(Long.TYPE, syntaxHandler);
                break;

            default:
                break;

            }

            final URI syntaxUri = systemSyntax.getSyntaxUri();
            loadSyntaxInternal(syntaxUri, syntaxHandler);
        }

        final Context context = getContext();

        // Loop again to build the system Syntax models now that the
        for (final SystemSyntax systemSyntax : SystemSyntax.values()) {
            final Syntax syntax = context.newModel(Syntax.class);

            final URI syntaxUri = systemSyntax.getSyntaxUri();
            syntax.setUniqueName(systemSyntax.getUniqueName());
            syntax.setUri(syntaxUri);

            _SystemSyntaxes.put(syntaxUri, syntax);
        }

    }

    protected void loadConfiguredSyntaxes() {

        final Context context = getContext();
        final ContextConfiguration contextConfig = context.getConfig();
        final SyntaxLoaderConfiguration config = contextConfig.getSyntaxLoader();
        if (config == null) {
            return;
        }

        final SyntaxConfiguration[] syntaxConfigs = config.getSyntaxes();
        if ((syntaxConfigs == null) || (syntaxConfigs.length == 0)) {
            return;
        }

        for (final SyntaxConfiguration syntaxConfiguration : syntaxConfigs) {
            loadConfiguredSyntax(syntaxConfiguration);
        }

    }
}