blob: f4745348cb351aebfdc35b6adaa63e5e71d4fb65 [file] [log] [blame]
/*
* Copyright (C) 2012 The Android Open Source Project
*
* 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.android.sched.reflections;
import com.android.sched.SchedProperties;
import com.android.sched.item.AbstractItemManager;
import com.android.sched.item.Item;
import com.android.sched.item.ItemSet;
import com.android.sched.item.Items;
import com.android.sched.item.ManagedItem;
import com.android.sched.item.onlyfor.Default;
import com.android.sched.item.onlyfor.OnlyForType;
import com.android.sched.util.config.ThreadConfig;
import com.android.sched.util.log.LoggerFactory;
import com.android.sched.util.sched.ManagedDataListener;
import com.android.sched.util.sched.ManagedDataListenerFactory;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.annotation.Nonnull;
/**
* Implementation of {@link AbstractItemManager} that uses the library {@code org.reflections} to
* access subtypes of the considered {@link Item} type by reflection.
*/
public class ItemManager extends AbstractItemManager {
@Nonnull
private final Logger logger = LoggerFactory.getLogger();
@Nonnull
private final Class<? extends OnlyForType> onlyFor = ThreadConfig.get(SchedProperties.ONLY_FOR);
@Nonnull
private final ManagedDataListener listener = ManagedDataListenerFactory.getManagedDataListener();
@Nonnull
private final Class<? extends Item> type;
public ItemManager(@Nonnull ReflectionManager reflectionManager,
@Nonnull Class<? extends Item> type) {
this.type = type;
scan(reflectionManager);
}
@Nonnull
@Override
public Class<? extends Item> getType() {
return type;
}
private void scan(@Nonnull ReflectionManager reflectionManager) {
// Discover all items
for (Class<? extends Item> item : reflectionManager.getSubTypesOf(type)) {
if (!isToIgnore(item)) {
ManagedItem ii = registerItem(item);
logger.log(Level.INFO, "Register {0} ({1})", new Object[] {ii, item.getCanonicalName()});
} else {
logger.log(Level.INFO, "Item ''{0}'' ({1}) is ignored because only for {2}",
new Object[] {Items.getName(item), item.getCanonicalName(), onlyFor.getSimpleName()});
}
}
logger.log(Level.INFO, "Register {0} item(s) in {1} integer(s)",
new Object[] {Integer.valueOf(getItemsCount()), Integer.valueOf(getIntegersCount())});
for (ManagedItem item : map.values()) {
Class<? extends Item> cls = item.getItem();
for (Class<?> sup : reflectionManager.getSuperTypesOf(cls)) {
ManagedItem managedSup = map.get(sup);
if (managedSup != null) {
managedSup.addComposedOf(item);
}
}
}
// Add missing @ComposedOf
for (ManagedItem item : map.values()) {
item.addComposedOf();
}
// Notify & log items
for (ManagedItem item : map.values()) {
listener.notifyNewManagedItem(item);
if (logger.isLoggable(Level.FINER)) {
ItemSet<Item> set = new ItemSet<Item>(this);
set.add(item.getItem());
logger.log(Level.FINER, "Item {0} is {1}", new Object[] {item, set});
}
}
listener.notifyNoMoreManagedItem(type);
}
private boolean isToIgnore(Class<? extends Item> item) {
Class<? extends OnlyForType> onlyFor = Items.getOnlyForType(item);
return onlyFor != Default.class && onlyFor != this.onlyFor;
}
}