
net.sf.robocode.repository.RepositoryManager Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of robocode.repository Show documentation
Show all versions of robocode.repository Show documentation
Build the best - destroy the rest!
/*
* Copyright (c) 2001-2023 Mathew A. Nelson and Robocode contributors
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* https://robocode.sourceforge.io/license/epl-v10.html
*/
package net.sf.robocode.repository;
import net.sf.robocode.core.Container;
import net.sf.robocode.io.FileUtil;
import net.sf.robocode.io.Logger;
import net.sf.robocode.io.URLJarCollector;
import net.sf.robocode.repository.items.IRepositoryItem;
import net.sf.robocode.repository.items.RobotItem;
import net.sf.robocode.repository.items.TeamItem;
import net.sf.robocode.repository.items.RepositoryItem;
import net.sf.robocode.repository.packager.JarCreator;
import net.sf.robocode.repository.root.IRepositoryRoot;
import net.sf.robocode.repository.root.handlers.RootHandler;
import net.sf.robocode.security.HiddenAccess;
import net.sf.robocode.settings.ISettingsListener;
import net.sf.robocode.settings.ISettingsManager;
import net.sf.robocode.ui.IWindowManager;
import robocode.control.RobotSpecification;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.StringTokenizer;
/**
* @author Pavel Savara (original)
*/
public class RepositoryManager implements IRepositoryManager { // NO_UCD (use default)
private static final String DATABASE_FILENAME = "robot.database";
private final ISettingsManager properties;
private Repository repository;
public RepositoryManager(ISettingsManager properties) { // NO_UCD (unused code)
this.properties = properties;
properties.addPropertyListener(new SettingsListener());
}
// ------------------------------------------
// interfaces
// ------------------------------------------
@Override
public File getRobotsDirectory() {
return FileUtil.getRobotsDir();
}
@Override
public List getDevelDirectories() {
List develDirectories = new ArrayList();
for (String path : properties.getOptionsEnabledDevelopmentPaths()) {
try {
develDirectories.add(new File(path).getCanonicalFile());
} catch (IOException e) {
Logger.logError(e);
}
}
return develDirectories;
}
public void refresh(String friendlyUrl) {
if (!updateItemRoot(friendlyUrl, true)) {
refresh(true);
}
URLJarCollector.gc();
}
public boolean refresh() {
return refresh(false);
}
public boolean refresh(boolean force) {
boolean refreshed = update(getRobotsDirectory(), getDevelDirectories(), force);
if (refreshed) {
setStatus("Saving robot database");
save();
}
setStatus("");
URLJarCollector.gc();
return refreshed;
}
private boolean update(File robotsDir, Collection devDirs, boolean force) {
final int prev = repository.getItems().size();
RootHandler.openHandlers();
try {
Map newRoots = new HashMap();
RootHandler.visitDirectories(robotsDir, false, newRoots, repository, force);
for (File dir : devDirs) {
RootHandler.visitDirectories(dir, true, newRoots, repository, force);
}
repository.setRoots(newRoots);
} finally {
RootHandler.closeHandlers();
}
return prev != repository.getItems().size();
}
private boolean updateItemRoot(String friendlyUrl, boolean force) {
IRepositoryItem repositoryItem = repository.getItems().get(friendlyUrl);
if (repositoryItem != null) {
repositoryItem.getRoot().updateItem(repositoryItem, force);
return true;
}
return false;
}
private void save() {
FileOutputStream fos = null;
try {
fos = new FileOutputStream(new File(getRobotsDirectory(), DATABASE_FILENAME));
repository.save(fos);
} catch (IOException e) {
Logger.logError("Can't save robot database", e);
} finally {
FileUtil.cleanupStream(fos);
}
}
private Repository load() {
Repository repository = new Repository();
FileInputStream fis = null;
try {
File file = new File(getRobotsDirectory(), DATABASE_FILENAME);
if (file.exists()) {
fis = new FileInputStream(file);
repository.load(fis);
}
} catch (IOException e) {
Logger.logError("Can't load robot database", e);
repository = null;
} finally {
FileUtil.cleanupStream(fis);
}
return repository;
}
public void reload(boolean rebuild) {
// Bug fix [2867326] - Lockup on start if too many bots in robots dir (cont'd).
URLJarCollector.enableGc(true);
URLJarCollector.gc();
if (rebuild) {
Logger.logMessage("Rebuilding robot database...");
repository = new Repository();
} else if (repository == null) {
setStatus("Reading robot database");
repository = load();
if (repository == null) {
setStatus("Building robot database");
repository = new Repository();
}
}
refresh(true);
setStatus("");
}
public RobotSpecification[] getSpecifications() {
checkDbExists();
final Collection list = getAllValidItems();
Collection res = new ArrayList();
for (IRobotSpecItem s : list) {
res.add(s.createRobotSpecification());
}
return res.toArray(new RobotSpecification[res.size()]);
}
/**
* Expand teams, validate robots
* @param selectedRobots, names of robots and teams, comma separated
* @return robots in teams
*/
public RobotSpecification[] loadSelectedRobots(RobotSpecification[] selectedRobots) {
checkDbExists();
Collection battlingRobotsList = new ArrayList();
int teamNum = 0;
for (RobotSpecification spec: selectedRobots) {
IRobotSpecItem item = (IRobotSpecItem) HiddenAccess.getFileSpecification(spec);
if (item == null) {
item = getRobot(spec.getNameAndVersion());
}
loadItem(battlingRobotsList, spec, item, teamNum);
teamNum++;
}
return battlingRobotsList.toArray(new RobotSpecification[battlingRobotsList.size()]);
}
/**
* Expand teams, validate robots
* @param selectedRobots, names of robots and teams, comma separated
* @return robots in teams
*/
public RobotSpecification[] loadSelectedRobots(String selectedRobots) {
checkDbExists();
Collection battlingRobotsList = new ArrayList();
final Collection list = getValidItems(selectedRobots);
int teamNum = 0;
for (IRobotSpecItem item: list) {
loadItem(battlingRobotsList, null, item, teamNum);
teamNum++;
}
return battlingRobotsList.toArray(new RobotSpecification[battlingRobotsList.size()]);
}
private boolean loadItem(Collection battlingRobotsList, RobotSpecification spec, IRobotSpecItem item, int teamNum) {
String teamName = String.format("%4d", teamNum);
if (item != null) {
if (item.isTeam()) {
teamName = item.getFullClassNameWithVersion() + "[" + teamName + "]";
final Collection members = getRobotItems((TeamItem) item);
for (IRobotSpecItem member : members) {
final RobotItem robot = (RobotItem) member;
boolean tested = false;
for (RobotSpecification loaded : battlingRobotsList) {
if (HiddenAccess.getFileSpecification(loaded).equals(robot)) {
tested = true;
break;
}
}
if (tested || robot.validate()) {
battlingRobotsList.add(robot.createRobotSpecification(null, teamName));
}
}
} else {
final RobotItem robot = (RobotItem) item;
if (robot.validate()) {
battlingRobotsList.add(robot.createRobotSpecification(spec, null));
} else {
Logger.logError("Could not load robot: " + robot.getFullClassName());
return false;
}
}
return true;
}
return false;
}
public List getSelectedSpecifications(String selectedRobots) {
checkDbExists();
return getValidItems(selectedRobots);
}
private Collection getAllValidItems() {
final ArrayList res = new ArrayList();
for (IRepositoryItem repositoryItem : repository.getItems().values()) {
final IRobotSpecItem spec = (IRobotSpecItem) repositoryItem;
if (repositoryItem.isValid() && !res.contains(spec)) {
res.add(spec);
}
}
return res;
}
private List getValidItems(String friendlyUrls) {
List result = new ArrayList();
StringTokenizer tokenizer = new StringTokenizer(friendlyUrls, ",");
while (tokenizer.hasMoreTokens()) {
String friendlyUrl = tokenizer.nextToken().trim();
IRepositoryItem repositoryItem = repository.getItem(friendlyUrl);
if (repositoryItem != null) {
if (repositoryItem.isValid()) {
result.add((IRobotSpecItem) repositoryItem);
} else {
Logger.logError("Can't load '" + friendlyUrl + "' because it is an invalid robot or team.");
}
} else {
Logger.logError("Can't find '" + friendlyUrl + '\'');
}
}
return result;
}
public List getRepositoryItems(boolean onlyWithSource, boolean onlyWithPackage, boolean onlyRobots, boolean onlyDevelopment, boolean onlyNotDevelopment, boolean ignoreTeamRobots, boolean onlyInJar) {
checkDbExists();
final List res = new ArrayList();
for (IRepositoryItem repositoryItem : repository.getItems().values()) {
final IRobotSpecItem spec = (IRobotSpecItem) repositoryItem;
if (!repositoryItem.isValid()) {
continue;
}
if (onlyWithSource && !spec.isSourceIncluded()) {
continue;
}
if (onlyWithPackage && spec.getFullPackage() == null) {
continue;
}
if (onlyInJar && !spec.isInJAR()) {
continue;
}
if (onlyRobots && !(repositoryItem instanceof RobotItem)) {
continue;
}
if (onlyDevelopment && !spec.isDevelopmentVersion()) {
continue;
}
if (onlyNotDevelopment && spec.isDevelopmentVersion()) {
continue;
}
if (res.contains(spec)) {
continue;
}
res.add(spec);
}
Collections.sort(res);
return res;
}
public boolean verifyRobotName(String robotName, String shortClassName) {
return RobotItem.verifyRobotName(robotName, shortClassName, true);
}
public int extractJar(IRobotSpecItem item) {
if (!item.isInJAR()) {
return -2;
}
((RepositoryItem) item).getRoot().extractJAR();
return 0;
}
public void createTeam(File target, TeamProperties teamProps) throws IOException {
checkDbExists();
TeamItem.createOrUpdateTeam(target, teamProps);
refresh(target.toURI().toString());
}
public String createPackage(File jarFile, List selectedRobots, RobotProperties robotProps) {
checkDbExists();
List robotItems = getAllRobotItems(selectedRobots);
TeamItem teamItem = getTeamItem(selectedRobots);
String res = JarCreator.createPackage(jarFile, robotItems, teamItem, robotProps);
refresh(jarFile.toURI().toString());
return res;
}
private Collection getRobotItems(TeamItem team) {
Collection result = new ArrayList();
StringTokenizer teamTokenizer = new StringTokenizer(team.getMembers(), ",");
while (teamTokenizer.hasMoreTokens()) {
String botNameAndVersion = teamTokenizer.nextToken();
int versionIndex = botNameAndVersion.indexOf(' ');
String botPath = versionIndex < 0 ? botNameAndVersion : botNameAndVersion.substring(0, versionIndex);
botPath = botPath.replace('.', '/').replaceAll("\\*", "");
// first load from same classPath
String teamBot = team.getRoot().getURL() + botPath;
IRepositoryItem res = repository.getItem(teamBot);
if (res != null && res instanceof RobotItem) {
result.add((RobotItem) res);
continue;
}
// try general search
res = repository.getItem(botNameAndVersion);
if (res != null && res instanceof RobotItem) {
result.add((RobotItem) res);
continue;
}
// not found
Logger.logError("Can't find robot: " + botNameAndVersion);
}
return result;
}
private List getAllRobotItems(Collection items) {
List result = new ArrayList();
for (IRobotSpecItem item : items) {
if (item.isTeam()) {
result.addAll(getRobotItems((TeamItem) item));
} else {
result.add((RobotItem) item);
}
}
return result;
}
private static TeamItem getTeamItem(Collection items) {
for (IRobotSpecItem item : items) {
if (item.isTeam()) {
return (TeamItem) item;
}
}
return null;
}
private IRobotSpecItem getRobot(String fullClassNameWithVersion) {
final IRepositoryItem repositoryItem = repository.getItem(fullClassNameWithVersion);
if (repositoryItem == null || !repositoryItem.isValid()) {
return null;
}
return (IRobotSpecItem) repositoryItem;
}
private void setStatus(String message) {
IWindowManager windowManager = Container.getComponent(IWindowManager.class);
if (windowManager != null) {
windowManager.setStatus(message);
}
if (message.length() > 0) {
Logger.logMessage(message);
}
}
private void checkDbExists() {
if (repository == null) {
reload(false);
}
}
// ------------------------------------------
// settings listener
// ------------------------------------------
private class SettingsListener implements ISettingsListener {
private Collection lastEnabledDevelPaths;
public void settingChanged(String property) {
if (property.equals(ISettingsManager.OPTIONS_DEVELOPMENT_PATH)
|| property.equals(ISettingsManager.OPTIONS_DEVELOPMENT_PATH_EXCLUDED)) {
Collection enabledDevelPaths = properties.getOptionsEnabledDevelopmentPaths();
if (lastEnabledDevelPaths == null || !enabledDevelPaths.equals(lastEnabledDevelPaths)) {
lastEnabledDevelPaths = enabledDevelPaths;
reload(false);
}
}
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy