/*
* Copyright (C) 2011 Rhegium Team
*
* 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.rhegium.api.mvc;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.sourceprojects.cappadocia.ClassInfo;
import org.sourceprojects.cappadocia.ClassPool;
import org.sourceprojects.cappadocia.ClassQuery;
import org.sourceprojects.cappadocia.builder.ClassAttributeConstraintSelector;
import org.sourceprojects.cappadocia.builder.ClassQueryBuilder;
import com.google.inject.AbstractModule;
import com.google.inject.Singleton;
import com.google.inject.multibindings.Multibinder;
public class MvcModule extends AbstractModule {
private static final Logger LOG = LoggerFactory.getLogger(MvcModule.class);
private static Collection<Class<? extends Controller<?, ?, ?>>> COMPONENT_CONTROLLERS = new ArrayList<Class<? extends Controller<?, ?, ?>>>();
private static Collection<Class<? extends View<?, ?, ?>>> VIEWS = new ArrayList<Class<? extends View<?, ?, ?>>>();
static {
reloadClassPool();
}
@Override
@SuppressWarnings("rawtypes")
protected void configure() {
Multibinder<Controller> binder = Multibinder.newSetBinder(binder(), Controller.class);
for (Class<? extends Controller<?, ?, ?>> componentController : COMPONENT_CONTROLLERS) {
binder.addBinding().to(componentController).in(Singleton.class);
}
for (Class<? extends View<?, ?, ?>> view : VIEWS) {
bind(view);
}
}
@SuppressWarnings("unchecked")
private static Collection<Class<? extends Controller<?, ?, ?>>> findComponentControllers(final ClassPool classPool) {
LOG.info("Searching available ComponentControllers...");
ClassQuery query = new ClassQueryBuilder() {
@Override
protected ClassAttributeConstraintSelector configure() {
return where().subclassOf(AbstractController.class.getCanonicalName());
}
}.build();
if (classPool == null) {
return Collections.emptyList();
}
Collection<ClassInfo> classInfos = query.list(classPool);
Collection<Class<? extends Controller<?, ?, ?>>> classes = new ArrayList<Class<? extends Controller<?, ?, ?>>>();
for (ClassInfo classInfo : classInfos) {
if (classInfo != null && classInfo.isAbstract()) {
continue;
}
try {
LOG.info("\tFound ComponentController " + classInfo.getCanonicalName());
classes.add((Class<? extends Controller<?, ?, ?>>) Class.forName(classInfo.getCanonicalName()));
}
catch (Exception e) {
LOG.warn("Class " + classInfo.getCanonicalName() + " not found");
}
}
return classes;
}
@SuppressWarnings("unchecked")
private static Collection<Class<? extends View<?, ?, ?>>> findViews(final ClassPool classPool) {
LOG.info("Searching available Views...");
ClassQuery query = new ClassQueryBuilder() {
@Override
protected ClassAttributeConstraintSelector configure() {
return where().subclassOf(AbstractController.class.getCanonicalName());
}
}.build();
if (classPool == null) {
return Collections.emptyList();
}
Collection<ClassInfo> classInfos = query.list(classPool);
Collection<Class<? extends View<?, ?, ?>>> classes = new ArrayList<Class<? extends View<?, ?, ?>>>();
for (ClassInfo classInfo : classInfos) {
if (classInfo != null && classInfo.isAbstract()) {
continue;
}
try {
LOG.info("\tFound View " + classInfo.getCanonicalName());
classes.add((Class<? extends View<?, ?, ?>>) Class.forName(classInfo.getCanonicalName()));
}
catch (Exception e) {
LOG.warn("Class " + classInfo.getCanonicalName() + " not found");
}
}
return classes;
}
/**
* Just to use prebuild of the collections.
*/
public static void load() {
}
public static void reloadClassPool() {
try {
ClassPool classPool = new ClassPool();
classPool.addClasspath();
COMPONENT_CONTROLLERS.clear();
COMPONENT_CONTROLLERS.addAll(findComponentControllers(classPool));
VIEWS.clear();
VIEWS.addAll(findViews(classPool));
}
catch (Exception e) {
e.printStackTrace();
}
}
}