Package org.terasology.reflection.metadata

Source Code of org.terasology.reflection.metadata.AbstractClassLibrary

/*
* Copyright 2013 MovingBlocks
*
* 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.terasology.reflection.metadata;

import com.google.common.collect.HashBasedTable;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.google.common.collect.Table;
import org.terasology.engine.SimpleUri;
import org.terasology.engine.module.ModuleManager;
import org.terasology.module.Module;
import org.terasology.naming.Name;
import org.terasology.reflection.copy.CopyStrategyLibrary;
import org.terasology.reflection.reflect.ReflectFactory;
import org.terasology.registry.CoreRegistry;

import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;

/**
* Abstract base implement of ClassLibrary.
*
* @author Immortius
*/
public abstract class AbstractClassLibrary<T> implements ClassLibrary<T> {

    private ModuleManager moduleManager = CoreRegistry.get(ModuleManager.class);
    private CopyStrategyLibrary copyStrategyLibrary;
    private ReflectFactory reflectFactory;

    private Map<Class<? extends T>, ClassMetadata<? extends T, ?>> classLookup = Maps.newHashMap();
    private Table<Name, Name, ClassMetadata<? extends T, ?>> uriLookup = HashBasedTable.create();

    public AbstractClassLibrary(ReflectFactory factory, CopyStrategyLibrary copyStrategies) {
        this.reflectFactory = factory;
        this.copyStrategyLibrary = copyStrategies;
    }

    /**
     * @param type A type being registered into the library
     * @param name The name for the type
     * @param <C>  The class of the type
     * @return An instance of ClassMetadata (or a subtype) providing metadata for the given type
     */
    protected abstract <C extends T> ClassMetadata<C, ?> createMetadata(Class<C> type, ReflectFactory factory, CopyStrategyLibrary copyStrategies, SimpleUri name);

    @Override
    public void register(SimpleUri uri, Class<? extends T> clazz) {
        ClassMetadata<? extends T, ?> metadata = createMetadata(clazz, reflectFactory, copyStrategyLibrary, uri);

        if (metadata != null) {
            classLookup.put(clazz, metadata);
            uriLookup.put(uri.getObjectName(), uri.getModuleName(), metadata);
        }
    }

    @Override
    @SuppressWarnings("unchecked")
    public <U extends T> ClassMetadata<U, ?> getMetadata(Class<U> clazz) {
        if (clazz == null) {
            return null;
        }
        return (ClassMetadata<U, ?>) classLookup.get(clazz);
    }

    @Override
    @SuppressWarnings("unchecked")
    public <U extends T> ClassMetadata<U, ?> getMetadata(U object) {
        if (object != null) {
            return getMetadata((Class<U>) (object.getClass()));
        }
        return null;
    }

    @Override
    public <TYPE extends T> TYPE copy(TYPE object) {
        ClassMetadata<TYPE, ?> info = getMetadata(object);
        if (info != null) {
            return info.copy(object);
        }
        return null;
    }

    @Override
    public ClassMetadata<? extends T, ?> getMetadata(SimpleUri uri) {
        return uriLookup.get(uri.getObjectName(), uri.getModuleName());
    }

    @Override
    public Iterator<ClassMetadata<? extends T, ?>> iterator() {
        return classLookup.values().iterator();
    }

    @Override
    public List<ClassMetadata<? extends T, ?>> getMetadata(String name) {
        return getMetadata(new Name(name));
    }

    @Override
    public List<ClassMetadata<? extends T, ?>> getMetadata(Name name) {
        return Lists.newArrayList(uriLookup.row(name).values());
    }

    @Override
    public ClassMetadata<? extends T, ?> resolve(String name, Name context) {
        Module moduleContext = moduleManager.getEnvironment().get(context);
        if (moduleContext != null) {
            return resolve(name, moduleContext);
        }
        return null;
    }

    @Override
    public ClassMetadata<? extends T, ?> resolve(String name) {
        SimpleUri uri = new SimpleUri(name);
        if (uri.isValid()) {
            return getMetadata(uri);
        }
        List<ClassMetadata<? extends T, ?>> possibilities = getMetadata(name);
        if (possibilities.size() == 1) {
            return possibilities.get(0);
        }
        return null;
    }

    @Override
    public ClassMetadata<? extends T, ?> resolve(String name, Module context) {
        SimpleUri uri = new SimpleUri(name);
        if (uri.isValid()) {
            return getMetadata(uri);
        }
        List<ClassMetadata<? extends T, ?>> possibilities = getMetadata(name);
        switch (possibilities.size()) {
            case 0:
                return null;
            case 1:
                return possibilities.get(0);
            default:
                if (context != null) {
                    Set<Name> dependencies = moduleManager.getEnvironment().getDependencyNamesOf(context.getId());
                    Iterator<ClassMetadata<? extends T, ?>> iterator = possibilities.iterator();
                    while (iterator.hasNext()) {
                        ClassMetadata<? extends T, ?> metadata = iterator.next();
                        if (context.getId().equals(metadata.getUri().getModuleName())) {
                            return metadata;
                        }
                        if (!dependencies.contains(metadata.getUri().getModuleName())) {
                            iterator.remove();
                        }
                    }
                    if (possibilities.size() == 1) {
                        return possibilities.get(0);
                    }
                }
                return null;
        }
    }
}
TOP

Related Classes of org.terasology.reflection.metadata.AbstractClassLibrary

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.