/*
* Copyright 2010, Maarten Billemont
*
* 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 com.lyndir.omicron.api;
import com.lyndir.lhunath.opal.system.error.InternalInconsistencyException;
import com.lyndir.lhunath.opal.system.logging.Logger;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import javax.annotation.Nonnull;
/**
* @author lhunath, 2013-08-02
*/
@SuppressWarnings("FieldNameHidesFieldInSuperclass")
public abstract class ModuleType<M extends IModule> extends PublicModuleType<M> {
static final Logger logger = Logger.get( ModuleType.class );
public static final ModuleType<ExtractorModule> EXTRACTOR = //
new ModuleType<ExtractorModule>( ExtractorModule.class, PublicModuleType.EXTRACTOR.getStandardCost() ) {};
@SuppressWarnings("FieldNameHidesFieldInSuperclass")
public static final ModuleType<ContainerModule> CONTAINER = //
new ModuleType<ContainerModule>( ContainerModule.class, PublicModuleType.CONTAINER.getStandardCost() ) {};
@SuppressWarnings("FieldNameHidesFieldInSuperclass")
public static final ModuleType<MobilityModule> MOBILITY = //
new ModuleType<MobilityModule>( MobilityModule.class, PublicModuleType.MOBILITY.getStandardCost() ) {};
@SuppressWarnings("FieldNameHidesFieldInSuperclass")
public static final ModuleType<ConstructorModule> CONSTRUCTOR = //
new ModuleType<ConstructorModule>( ConstructorModule.class, PublicModuleType.CONSTRUCTOR.getStandardCost() ) {};
@SuppressWarnings("FieldNameHidesFieldInSuperclass")
public static final ModuleType<BaseModule> BASE = //
new ModuleType<BaseModule>( BaseModule.class, PublicModuleType.BASE.getStandardCost() ) {};
@SuppressWarnings("FieldNameHidesFieldInSuperclass")
public static final ModuleType<WeaponModule> WEAPON = //
new ModuleType<WeaponModule>( WeaponModule.class, PublicModuleType.WEAPON.getStandardCost() ) {};
private ModuleType(@Nonnull final Class<M> moduleType, @Nonnull final ImmutableResourceCost standardCost) {
super( moduleType, standardCost );
}
public static <M extends IModule> ModuleType<M> of(final PublicModuleType<M> moduleType) {
if (moduleType instanceof ModuleType)
return (ModuleType<M>) moduleType;
for (final Field field : ModuleType.class.getFields())
if (Modifier.isStatic( field.getModifiers() ))
if (ModuleType.class.isAssignableFrom( field.getType() ))
try {
ModuleType<?> coreModuleType = (ModuleType<?>) field.get( null );
if (moduleType.getModuleType().isAssignableFrom( coreModuleType.getModuleType() ))
//noinspection unchecked
return (ModuleType<M>) coreModuleType;
}
catch (final IllegalAccessException e) {
throw new InternalInconsistencyException( "Expected field to contain a core module: " + field, e );
}
throw new InternalInconsistencyException( "No core module field found for module type: " + moduleType );
}
}