/*
* (c) Copyright 2010-2011 AgileBirds
*
* This file is part of OpenFlexo.
*
* OpenFlexo is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* OpenFlexo is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with OpenFlexo. If not, see <http://www.gnu.org/licenses/>.
*
*/
package org.openflexo.foundation.rm;
import java.io.FileNotFoundException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.openflexo.foundation.FlexoException;
import org.openflexo.foundation.utils.ProjectLoadingCancelledException;
public abstract class FlexoImportedResource<RD extends ImportedResourceData> extends FlexoFileResource<RD> {
private static final Logger logger = Logger.getLogger(FlexoImportedResource.class.getPackage().getName());
private Date _lastImportDate;
public FlexoImportedResource(FlexoProject aProject) {
super(aProject);
}
protected abstract RD doImport() throws FlexoException;
@Override
protected void performUpdating(FlexoResourceTree updatedResources) throws FileNotFoundException, ResourceDependencyLoopException,
FlexoException {
if (!isLoaded()) {
importResourceData();
}
backwardSynchronizeWith(updatedResources);
}
public RD importResourceData() throws LoadResourceException {
try {
_resourceData = doImport();
_lastImportDate = new Date();
notifyResourceChanged();
return _resourceData;
} catch (FlexoException e) {
e.printStackTrace();
throw new ImportResourceException(this);
}
}
public final void backwardSynchronizeWith(FlexoResourceTree updatedResources) throws ResourceDependencyLoopException, FlexoException,
FileNotFoundException {
if (!updatedResources.isEmpty()) {
if (logger.isLoggable(Level.FINE)) {
logger.fine("Resource " + this + " requires backward synchronization for " + updatedResources.getChildNodes().size()
+ " resources :");
}
for (FlexoResourceTree resourceTrees : updatedResources.getChildNodes()) {
FlexoResource resource = resourceTrees.getRootNode();
resource.update();
if (FlexoResourceManager.getBackwardSynchronizationHook() != null) {
FlexoResourceManager.getBackwardSynchronizationHook().notifyBackwardSynchronization(this, resource);
}
backwardSynchronizeWith(resource);
}
}
}
public void backwardSynchronizeWith(FlexoResource aResource) throws FlexoException {
// Must be called sub sub-classes implementation: must be overriden in subclasses !
// At this level, only set last synchronized date
if (logger.isLoggable(Level.FINER)) {
logger.finer("Backsynchronizing " + this + " with " + aResource);
}
setLastSynchronizedWithResource(aResource, new Date());
getProject().notifyResourceHasBeenBackwardSynchronized(this);
}
/**
* Return a flag indicating if resource is loaded in memory
*
* @return
*/
public synchronized boolean isLoaded() {
return _resourceData != null;
}
public Date getLastImportDate() {
return _lastImportDate;
}
public void setLastImportDate(Date aDate) {
_lastImportDate = aDate;
}
@Override
protected boolean requireUpdateBecauseOf(FlexoResource resource) {
if (super.requireUpdateBecauseOf(resource)) {
// OK, at first sight 'resource' of which 'this' depends is newer than 'this' so it seems that we need to update 'this'. BUT,
// maybe
// the modifications of 'resource' does not affect 'this', therefore we will look at the lastSynchronizationDate
Date lastBackSynchronizationDate = getLastSynchronizedWithResource(resource);
if (!project.getTimestampsHaveBeenLoaded()) {
if (logger.isLoggable(Level.WARNING)) {
logger.warning("Time stamps not loaded yet!!! Impossible to say if we have to do something or not");
}
}
if (lastBackSynchronizationDate == null || resource.getLastUpdate().after(lastBackSynchronizationDate)) {
if (lastBackSynchronizationDate != null) {
if (logger.isLoggable(Level.FINER)) {
logger.finer("Resource " + this + " is to be backward synchronized for " + resource + " because "
+ new SimpleDateFormat("dd/MM HH:mm:ss SSS").format(resource.getLastUpdate()) + " is more recent than "
+ new SimpleDateFormat("dd/MM HH:mm:ss SSS").format(lastBackSynchronizationDate));
}
}
return true;
} else {
if (logger.isLoggable(Level.FINER)) {
logger.finer("NOT: Resource " + this + " must NOT be BS with " + resource + " because "
+ new SimpleDateFormat("dd/MM HH:mm:ss SSS").format(resource.getLastUpdate()) + " is more anterior than "
+ new SimpleDateFormat("dd/MM HH:mm:ss SSS").format(lastBackSynchronizationDate));
}
}
}
return false;
}
/**
* This date is VERY IMPORTANT and CRITICAL since this is the date used by ResourceManager to compute dependancies between resources.
* This method returns the date that must be considered as last known update for this resource
*
* @return a Date object
*/
@Override
public synchronized Date getLastUpdate() {
return getDiskLastModifiedDate();
}
/**
* Return data related to this resource, as an instance of an object implementing
*
* @see org.openflexo.foundation.rm.FlexoResourceData
* @return
* @throws FlexoException
* @throws ProjectLoadingCancelledException
* @throws FileNotFoundException
*/
public synchronized RD getImportedData() throws FileNotFoundException, ProjectLoadingCancelledException, FlexoException {
if (_resourceData == null) {
try {
// logger.info("getImportedData() in "+this);
update();
_resourceData = importResourceData();
} catch (LoadResourceException e) {
// Warns about the exception
if (logger.isLoggable(Level.WARNING)) {
logger.warning("Could not load resource data for resource " + getResourceIdentifier());
}
e.printStackTrace();
} catch (ResourceDependencyLoopException e) {
if (logger.isLoggable(Level.SEVERE)) {
logger.log(Level.SEVERE, "Loop in dependant resources of " + this + "!", e);
}
}
}
return _resourceData;
}
}