net.sf.robocode.repository.Repository Maven / Gradle / Ivy
/*
* 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.io.FileUtil;
import net.sf.robocode.io.Logger;
import net.sf.robocode.repository.items.IRepositoryItem;
import net.sf.robocode.repository.root.BaseRoot;
import net.sf.robocode.repository.root.IRepositoryRoot;
import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.OutputStream;
import java.net.URLDecoder;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
/**
* Repository containing robot and team repositoryItems.
*
* @author Pavel Savara (original)
* @author Flemming N. Larsen (contributor)
*/
class Repository implements IRepository {
private Map roots = new ConcurrentHashMap();
private final Map repositoryItems = new ConcurrentHashMap();
private final Map removedItems = new ConcurrentHashMap();
/**
* {@inheritDoc}
*/
public void save(OutputStream out) {
Set uniqueItems = new HashSet();
Set uniqueRoots = new HashSet();
for (IRepositoryItem repositoryItem : repositoryItems.values()) {
uniqueItems.add(repositoryItem);
}
for (IRepositoryRoot root : roots.values()) {
uniqueRoots.add(root);
}
ObjectOutputStream oos = null;
try {
oos = new ObjectOutputStream(out);
oos.writeObject(uniqueRoots);
oos.writeObject(uniqueItems);
} catch (IOException e) {
Logger.logError("Can't save robot database", e);
} finally {
FileUtil.cleanupStream(oos);
}
}
/**
* {@inheritDoc}
*/
@SuppressWarnings("unchecked")
public void load(InputStream in) {
Set uniqueItems;
Set uniqueRoots;
ObjectInputStream ois = null;
try {
ois = new ObjectInputStream(in);
uniqueRoots = (Set) ois.readObject();
uniqueItems = (Set) ois.readObject();
for (IRepositoryRoot root : uniqueRoots) {
((BaseRoot) root).setRepository(this);
String key = root.getURL().toString();
key = URLDecoder.decode(key, "UTF-8");
roots.put(key, root);
}
for (IRepositoryItem repositoryItem : uniqueItems) {
addOrUpdateItem(repositoryItem);
}
} catch (IOException e) {
Logger.logError("Can't load robot database: " + e.getMessage());
} catch (ClassNotFoundException e) {
Logger.logError("Can't load robot database: " + e.getMessage());
} finally {
FileUtil.cleanupStream(ois);
}
}
/**
* {@inheritDoc}
*/
public void addOrUpdateItem(IRepositoryItem repositoryItem) {
Collection friendlyUrls = repositoryItem.getFriendlyURLs();
if (friendlyUrls != null) {
// Add or update the item so it can be found using later using any friendly URL
for (String friendly : friendlyUrls) {
if (friendly != null) {
IRepositoryItem existingItem = repositoryItems.get(friendly);
// Add the item if it does not exist already, or update it if the version is newer
// than the existing item.
if (existingItem == null || repositoryItem.compareTo(existingItem) > 0) {
repositoryItems.put(friendly, repositoryItem);
}
}
}
}
}
/**
* {@inheritDoc}
*/
public IRepositoryItem getItem(String friendlyUrl) {
IRepositoryItem repositoryItem = repositoryItems.get(friendlyUrl);
if (repositoryItem == null) {
repositoryItem = removedItems.get(friendlyUrl);
}
return repositoryItem;
}
/**
* {@inheritDoc}
*/
public Map getItems() {
return Collections.unmodifiableMap(repositoryItems);
}
/**
* {@inheritDoc}
*/
public Map getRoots() {
return Collections.unmodifiableMap(roots);
}
/**
* {@inheritDoc}
*/
public void removeRoot(String friendlyUrl) {
roots.remove(friendlyUrl);
}
/**
* {@inheritDoc}
*/
public void removeItemsFromRoot(IRepositoryRoot root) {
Collection> itemsToRemove = new ArrayList>();
for (Map.Entry entry : repositoryItems.entrySet()) {
if (entry.getValue().getRoot().equals(root)) {
itemsToRemove.add(entry);
}
}
for (Map.Entry entry : itemsToRemove) {
String key = entry.getKey();
removedItems.put(key, entry.getValue());
repositoryItems.remove(key);
}
}
/**
* Replaces the repository roots with new repository roots.
*
* @param newRoots is the new repository roots for this repository.
*/
// Only for the RepositoryManager
public void setRoots(Map newRoots) {
// Remove all items from current roots
for (IRepositoryRoot root : roots.values()) {
if (!newRoots.containsKey(root.getURL().toString())) {
removeItemsFromRoot(root);
}
}
// Set the new roots
roots = newRoots;
// Clear items to be removed
removedItems.clear();
}
}