/* (c) 2014 - 2015 Open Source Geospatial Foundation - all rights reserved * (c) 2001 - 2013 OpenPlans * This code is licensed under the GPL 2.0 license, available at the root * application directory. */ package org.geoserver.importer; import static org.geoserver.importer.ImporterUtils.resolve; import java.io.IOException; import java.io.Serializable; import java.util.ArrayList; import java.util.Collections; import java.util.Date; import java.util.List; import java.util.logging.Logger; import org.geoserver.catalog.Catalog; import org.geoserver.catalog.StoreInfo; import org.geoserver.catalog.WorkspaceInfo; import org.geoserver.importer.job.ProgressMonitor; import org.geoserver.importer.transform.ImportTransform; import org.geoserver.importer.transform.RasterTransform; import org.geoserver.importer.transform.RasterTransformChain; import org.geoserver.importer.transform.TransformChain; import org.geoserver.importer.transform.VectorTransform; import org.geoserver.importer.transform.VectorTransformChain; import org.geotools.util.logging.Logging; /** * Maintains state about an import. * * @author Justin Deoliveira, OpenGeo * */ public class ImportContext implements Serializable { /** serialVersionUID */ private static final long serialVersionUID = 8790675013874051197L; static final Logger LOGGER = Logging.getLogger(ImportContext.class); public static enum State { /** * Context is ready to be initialized, but still misses tasks. Used to create a context * while planning for an asynchronous initialization */ INIT, /** * Context init failed */ INIT_ERROR, /** * Context ready to be started */ PENDING, /** * Import is running */ RUNNING, /** * Import is complete */ COMPLETE; } /** identifier */ Long id; /** state */ State state = State.PENDING; /** * data source */ ImportData data; /** * target workspace for the import */ WorkspaceInfo targetWorkspace; /** * target store of the import */ StoreInfo targetStore; /** * import tasks */ List<ImportTask> tasks = new ArrayList<ImportTask>(); /** * The default transformations that will be applied on task creation */ List<ImportTransform> defaultTransforms = new ArrayList<>(); /** * id generator for task */ int taskid = 0; /** * date import was created */ Date created; /** * date import was finished */ Date updated; /** * credentials of creator */ String user; /** * flag to control whether imported files (indirect) should be archived after import * JD: this used to be true by default, now false since by default importing a shapefile * directly from the local file system would result in the shapefile, and its parent directory * being deleted */ boolean archive = false; /** * Used for error messages */ String message; volatile ProgressMonitor progress; public ImportContext(long id) { this(); this.id = id; } public ImportContext() { this.created = new Date(); this.updated = new Date(created.getTime()); } public Long getId() { return id; } public void setId(Long id) { this.id = id; } public State getState() { return state; } public void setState(State state) { this.state = state; } public Date getCreated() { return created; } public Date getUpdated() { return updated; } public ImportData getData() { return data; } public void setData(ImportData data) { this.data = data; } public WorkspaceInfo getTargetWorkspace() { return targetWorkspace; } public void setTargetWorkspace(WorkspaceInfo targetWorkspace) { this.targetWorkspace = targetWorkspace; } public StoreInfo getTargetStore() { return targetStore; } public void setTargetStore(StoreInfo targetStore) { this.targetStore = targetStore; } public String getUser() { return user; } public void setUser(String user) { this.user = user; } public boolean isArchive() { return archive; } public void setArchive(boolean archive) { this.archive = archive; } public List<ImportTask> getTasks() { return Collections.unmodifiableList(tasks); } public void addTask(ImportTask task) { task.setId(taskid++); task.setContext(this); this.tasks.add(task); // apply the default transformations TransformChain chain = task.getTransform(); for (ImportTransform tx : defaultTransforms) { if (chain instanceof RasterTransformChain && tx instanceof RasterTransform) { chain.add(tx); } else if (chain instanceof VectorTransformChain && tx instanceof VectorTransform) { chain.add(tx); } } } public void removeTask(ImportTask task) { this.tasks.remove(task); } public ImportTask task(long id) { for (ImportTask t : tasks) { if (t.getId() == id) { return t; } } return null; } /** * Returns a live list with the default transform, can be modified directly to add/remove the * default transforms * * */ public List<ImportTransform> getDefaultTransforms() { return defaultTransforms; } private void updateState() { State newState; if (tasks.isEmpty()) { if (state == State.INIT) { newState = State.INIT; } else { newState = State.PENDING; } } else { newState = State.COMPLETE; } O: for (ImportTask task : tasks) { switch(task.getState()) { case COMPLETE: continue; case RUNNING: newState = State.RUNNING; break O; default: newState = State.PENDING; break O; } } state = newState; } public void updated() { updated = new Date(); updateState(); } public void delete() throws IOException { if (data != null) { data.cleanup(); } } public void reattach(Catalog catalog) { reattach(catalog, false); } public void reattach(Catalog catalog, boolean lookupByName) { if (data != null) { data.reattach(); } if (targetWorkspace != null) { targetWorkspace = resolve(targetWorkspace, catalog, lookupByName); if (targetStore != null) { targetStore.setWorkspace(targetWorkspace); } } targetStore = resolve(targetStore, catalog, lookupByName); for (ImportTask task : tasks) { task.setContext(this); task.reattach(catalog, lookupByName); } } public ProgressMonitor progress() { if (progress == null) { progress = new ProgressMonitor(); } return progress; } public void setProgress(ProgressMonitor progress) { this.progress = progress; } @Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + ((id == null) ? 0 : id.hashCode()); return result; } @Override public boolean equals(Object obj) { if (this == obj) return true; if (obj == null) return false; if (getClass() != obj.getClass()) return false; ImportContext other = (ImportContext) obj; if (id == null) { if (other.id != null) return false; } else if (!id.equals(other.id)) return false; return true; } private Object readResolve() { if (tasks == null) { tasks = new ArrayList<>(); } if (defaultTransforms == null) { defaultTransforms = new ArrayList<>(); } return this; } /** * Returns the current context message, if any * * @return the message */ public String getMessage() { return message; } /** * Sets the context message * * @param message the message to set */ public void setMessage(String message) { this.message = message; } }