package org.openflexo.foundation.resource; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.logging.Level; import org.apache.commons.io.IOUtils; import org.jdom2.JDOMException; import org.openflexo.foundation.ontology.OntologyLibrary; import org.openflexo.foundation.viewpoint.ViewPoint; import org.openflexo.foundation.viewpoint.ViewPointLibrary; import org.openflexo.localization.FlexoLocalization; import org.openflexo.model.annotations.Adder; import org.openflexo.model.annotations.Getter; import org.openflexo.model.annotations.Getter.Cardinality; import org.openflexo.model.annotations.Import; import org.openflexo.model.annotations.Imports; import org.openflexo.model.annotations.ModelEntity; import org.openflexo.model.annotations.Remover; import org.openflexo.model.annotations.Setter; import org.openflexo.model.annotations.XMLAttribute; import org.openflexo.model.annotations.XMLElement; import org.openflexo.model.exceptions.InvalidDataException; import org.openflexo.model.exceptions.ModelDefinitionException; import org.openflexo.model.factory.DeserializationPolicy; import org.openflexo.model.factory.ModelFactory; import org.openflexo.model.factory.SerializationPolicy; import org.openflexo.toolbox.IProgress; public class UserResourceCenter implements FlexoResourceCenter { private static final java.util.logging.Logger logger = org.openflexo.logging.FlexoLogger.getLogger(UserResourceCenter.class .getPackage().getName()); private ModelFactory modelFactory; private File userResourceCenterStorageFile; private Storage storage; public UserResourceCenter(File userResourceCenterStorageFile) { this.userResourceCenterStorageFile = userResourceCenterStorageFile; try { this.modelFactory = new ModelFactory(Storage.class); } catch (ModelDefinitionException e1) { // Hum this sucks... e1.printStackTrace(); } if (userResourceCenterStorageFile.exists() && userResourceCenterStorageFile.isFile()) { try { update(); } catch (IOException e) { e.printStackTrace(); } } else if (!userResourceCenterStorageFile.canRead() || !userResourceCenterStorageFile.canWrite()) { System.err.println("Permission denied for file " + userResourceCenterStorageFile.getAbsolutePath()); } if (storage == null) { storage = modelFactory.newInstance(Storage.class); } } public File getUserResourceCenterStorageFile() { return userResourceCenterStorageFile; } public void setUserResourceCenterStorageFile(File userResourceCenterStorageFile) { this.userResourceCenterStorageFile = userResourceCenterStorageFile; } @ModelEntity @XMLElement(xmlTag = "UserResourceCenter") @Imports({ @Import(FlexoFileResource.class) }) public static interface Storage { public static final String RESOURCES = "resources"; @Getter(value = RESOURCES, cardinality = Cardinality.LIST) @XMLElement public List<FlexoResource<?>> getResources(); @Setter(RESOURCES) public void setResources(List<FlexoResource<?>> resources); @Adder(RESOURCES) public void addToResources(FlexoResource<?> resource); @Remover(RESOURCES) public void removeFromResources(FlexoResource<?> resource); } @ModelEntity @XMLElement public static interface FlexoFileResource<RD extends ResourceData<RD>> extends FlexoResource<RD> { public static final String FILE = "file"; @Getter(FILE) @XMLAttribute public File getFile(); @Setter(FILE) public void setFile(File file); } @Override public List<FlexoResource<?>> getAllResources(IProgress progress) { return Collections.unmodifiableList(storage.getResources()); } @Override public <T extends ResourceData<T>> FlexoResource<T> retrieveResource(String uri, String version, Class<T> type, IProgress progress) { List<FlexoResource<?>> resources = storage.getResources(); if (progress != null) { progress.resetSecondaryProgress(resources.size()); } for (FlexoResource<?> resource : resources) { if (progress != null) { progress.setSecondaryProgress(FlexoLocalization.localizedForKey("retrieving_resource")); } if (resource.getURI().equals(uri)) { if (resource.getVersion() == null && version == null || resource.getVersion() != null && resource.getVersion().equals(version) && (type == null || type.isAssignableFrom(resource.getResourceDataClass()))) { return (FlexoResource<T>) resource; } } } return null; } @Override public <T extends ResourceData<T>> List<FlexoResource<T>> retrieveResource(String uri, Class<T> type, IProgress progress) { List<FlexoResource<T>> returned = new ArrayList<FlexoResource<T>>(); List<FlexoResource<?>> resources = storage.getResources(); if (progress != null) { progress.resetSecondaryProgress(resources.size()); } for (FlexoResource<?> resource : resources) { if (progress != null) { progress.setSecondaryProgress(FlexoLocalization.localizedForKey("retrieving_resources")); } if (resource.getURI().equals(uri)) { if (type.isAssignableFrom(resource.getResourceDataClass())) { returned.add((FlexoResource<T>) resource); } } } return returned; } @Override public void publishResource(FlexoResource<?> resource, String newVersion, IProgress progress) throws Exception { FlexoResource<?> oldResource = retrieveResource(resource.getURI(), newVersion, resource.getResourceDataClass(), progress); if (oldResource != null) { storage.removeFromResources(oldResource); } if (resource instanceof FlexoFileResource) { File file = ((FlexoFileResource<?>) resource).getFile(); if (file != null) { for (FlexoResource<?> r : new ArrayList<FlexoResource<?>>(storage.getResources())) { if (r instanceof FlexoFileResource) { if (((FlexoFileResource<?>) r).getFile().equals(file)) { storage.removeFromResources(r); } } } } } storage.addToResources(resource); saveStorage(); } private void saveStorage() throws IOException { if (!userResourceCenterStorageFile.exists()) { userResourceCenterStorageFile.getParentFile().mkdirs(); } FileOutputStream fos = new FileOutputStream(userResourceCenterStorageFile); try { modelFactory.serialize(storage, fos, SerializationPolicy.EXTENSIVE); } finally { IOUtils.closeQuietly(fos); } } @Override public void update() throws IOException { FileInputStream fis = new FileInputStream(userResourceCenterStorageFile); try { try { storage = (Storage) modelFactory.deserialize(fis, DeserializationPolicy.EXTENSIVE); if (logger.isLoggable(Level.INFO)) { logger.info("Loaded " + storage.getResources().size() + " resources from user resource cente file"); } } catch (JDOMException e) { e.printStackTrace(); throw new IOException("Parsing XML data failed: " + e.getMessage(), e); } catch (InvalidDataException e) { e.printStackTrace(); throw new IOException("Invalid XML data: " + e.getMessage(), e); } catch (ModelDefinitionException e) { // This should not happen e.printStackTrace(); } } finally { IOUtils.closeQuietly(fis); } checkKnownResources(); } private void checkKnownResources() throws IOException { if (storage != null) { boolean changed = false; for (FlexoResource<?> resource : storage.getResources()) { // TODO check resources } if (changed) { saveStorage(); } } } @Override public OntologyLibrary retrieveBaseOntologyLibrary() { return null; } @Override public ViewPointLibrary retrieveViewPointLibrary() { return null; } @Override public ViewPoint getOntologyCalc(String ontologyCalcUri) { return null; } @Override public File getNewCalcSandboxDirectory() { return new File(userResourceCenterStorageFile.getParentFile(), "ViewPoints"); } }