Move TypeManager.updatePrototype(Prototype) to Prototype.checkForUpdates().
Additionally, the inner workings of the Prototype update logic were vastly simplified.
This commit is contained in:
parent
57efa85f29
commit
fdf3915d9e
4 changed files with 95 additions and 160 deletions
|
@ -1743,7 +1743,9 @@ public final class Application implements IPathElement, Runnable {
|
|||
* change, too.
|
||||
*/
|
||||
public long getChecksum() {
|
||||
return starttime + typemgr.lastCodeUpdate() + props.getChecksum();
|
||||
return starttime +
|
||||
typemgr.getLastCodeUpdate() +
|
||||
props.getChecksum();
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -33,19 +33,21 @@ import java.util.*;
|
|||
* relational database table.
|
||||
*/
|
||||
public final class Prototype {
|
||||
// the app this prototype belongs to
|
||||
Application app;
|
||||
|
||||
// this prototype's name in natural and lower case
|
||||
String name;
|
||||
String lowerCaseName;
|
||||
|
||||
// this prototype's resources
|
||||
Resource[] resources;
|
||||
long lastResourceListing;
|
||||
|
||||
// lastCheck is the time the prototype's files were last checked
|
||||
long lastChecksum;
|
||||
long newChecksum;
|
||||
// lastUpdate is the time at which any of the prototype's files were found updated the last time
|
||||
long lastCodeUpdate;
|
||||
// tells us the checksum of the repositories at the time we last updated them
|
||||
long lastChecksum = 0;
|
||||
|
||||
// the time at which any of the prototype's files were found updated the last time
|
||||
long lastCodeUpdate = 0;
|
||||
|
||||
TreeSet code;
|
||||
TreeSet skins;
|
||||
|
@ -103,7 +105,6 @@ public final class Prototype {
|
|||
skinMap = new HashMap();
|
||||
|
||||
isJavaPrototype = app.isJavaPrototype(name);
|
||||
lastCodeUpdate = lastChecksum = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -125,13 +126,73 @@ public final class Prototype {
|
|||
}
|
||||
|
||||
/**
|
||||
* Returns the list of resources in this prototype's repositories
|
||||
* Check a prototype for new or updated resources. After this has been
|
||||
* called the code and skins collections of this prototype should be
|
||||
* up-to-date and the lastCodeUpdate be set if there has been any changes.
|
||||
*/
|
||||
public Resource[] getResources() {
|
||||
long resourceListing = getChecksum();
|
||||
public void checkForUpdates() {
|
||||
|
||||
if (resources == null || resourceListing != lastResourceListing) {
|
||||
lastResourceListing = resourceListing;
|
||||
boolean updatedResources = false;
|
||||
|
||||
// check if any resource the prototype knows about has changed or gone
|
||||
for (Iterator i = trackers.values().iterator(); i.hasNext();) {
|
||||
ResourceTracker tracker = (ResourceTracker) i.next();
|
||||
|
||||
try {
|
||||
if (tracker.hasChanged()) {
|
||||
updatedResources = true;
|
||||
tracker.markClean();
|
||||
if (!tracker.getResource().exists()) {
|
||||
i.remove();
|
||||
String name = tracker.getResource().getName();
|
||||
if (name.endsWith(TypeManager.skinExtension)) {
|
||||
skins.remove(tracker.getResource());
|
||||
} else {
|
||||
code.remove(tracker.getResource());
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (IOException iox) {
|
||||
iox.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
// next we check if resources have been created or removed
|
||||
Resource[] resources = getResources();
|
||||
|
||||
for (int i = 0; i < resources.length; i++) {
|
||||
String name = resources[i].getName();
|
||||
if (!trackers.containsKey(name)) {
|
||||
if (name.endsWith(TypeManager.templateExtension) ||
|
||||
name.endsWith(TypeManager.scriptExtension) ||
|
||||
name.endsWith(TypeManager.actionExtension) ||
|
||||
name.endsWith(TypeManager.skinExtension)) {
|
||||
|
||||
if (name.endsWith(TypeManager.skinExtension)) {
|
||||
addSkinResource(resources[i]);
|
||||
} else {
|
||||
addCodeResource(resources[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (updatedResources) {
|
||||
// mark prototype as dirty and the code as updated
|
||||
lastCodeUpdate = System.currentTimeMillis();
|
||||
app.typemgr.setLastCodeUpdate(lastCodeUpdate);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns the list of resources in this prototype's repositories. Used
|
||||
* by checkForUpdates() to see whether there is anything new.
|
||||
*/
|
||||
Resource[] getResources() {
|
||||
long checksum = getRepositoryChecksum();
|
||||
// reload resources if the repositories checksum has changed
|
||||
if (checksum != lastChecksum) {
|
||||
ArrayList list = new ArrayList();
|
||||
Iterator iterator = repositories.iterator();
|
||||
|
||||
|
@ -144,15 +205,16 @@ public final class Prototype {
|
|||
}
|
||||
|
||||
resources = (Resource[]) list.toArray(new Resource[list.size()]);
|
||||
lastChecksum = checksum;
|
||||
}
|
||||
|
||||
return resources;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a checksum over this prototype's sources
|
||||
* Get a checksum over this prototype's repositories. This tells us
|
||||
* if any resources were added or removed.
|
||||
*/
|
||||
public long getChecksum() {
|
||||
long getRepositoryChecksum() {
|
||||
long checksum = 0;
|
||||
Iterator iterator = repositories.iterator();
|
||||
|
||||
|
@ -164,20 +226,9 @@ public final class Prototype {
|
|||
}
|
||||
}
|
||||
|
||||
newChecksum = checksum;
|
||||
return checksum;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public boolean isUpToDate() {
|
||||
return (newChecksum == 0 && lastChecksum == 0) ?
|
||||
false : newChecksum == lastChecksum;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the parent prototype of this prototype, i.e. the prototype this
|
||||
* prototype inherits from.
|
||||
|
@ -241,18 +292,14 @@ public final class Prototype {
|
|||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param dbmap ...
|
||||
* Set the DbMapping associated with this prototype
|
||||
*/
|
||||
protected void setDbMapping(DbMapping dbmap) {
|
||||
this.dbmap = dbmap;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @return ...
|
||||
* Get the DbMapping associated with this prototype
|
||||
*/
|
||||
public DbMapping getDbMapping() {
|
||||
return dbmap;
|
||||
|
@ -316,15 +363,6 @@ public final class Prototype {
|
|||
lastCodeUpdate = System.currentTimeMillis();
|
||||
}
|
||||
|
||||
/**
|
||||
* Signal that the prototype's scripts have been checked for
|
||||
* changes.
|
||||
*/
|
||||
public void markChecked() {
|
||||
// lastCheck = System.currentTimeMillis ();
|
||||
lastChecksum = newChecksum;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a clone of this prototype's actions container. Synchronized
|
||||
* to not return a map in a transient state where it is just being
|
||||
|
@ -483,10 +521,6 @@ public final class Prototype {
|
|||
}
|
||||
|
||||
private void checkForUpdates() {
|
||||
if (!isUpToDate()) {
|
||||
app.typemgr.updatePrototype(Prototype.this);
|
||||
}
|
||||
|
||||
if (lastCodeUpdate > lastSkinmapLoad) {
|
||||
load();
|
||||
}
|
||||
|
|
|
@ -19,7 +19,6 @@ package helma.framework.core;
|
|||
import helma.objectmodel.db.DbMapping;
|
||||
import helma.framework.repository.Resource;
|
||||
import helma.framework.repository.Repository;
|
||||
import helma.framework.repository.ResourceTracker;
|
||||
|
||||
import java.io.*;
|
||||
import java.net.URL;
|
||||
|
@ -212,13 +211,20 @@ public final class TypeManager {
|
|||
}
|
||||
|
||||
/**
|
||||
* Return a checksum over all files in all prototypes in this application.
|
||||
* The checksum can be used to find out quickly if any file has changed.
|
||||
* Returns the last time any resource in this app was modified.
|
||||
* This can be used to find out quickly if any file has changed.
|
||||
*/
|
||||
public long lastCodeUpdate() {
|
||||
public long getLastCodeUpdate() {
|
||||
return lastCodeUpdate;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the last time any resource in this app was modified.
|
||||
*/
|
||||
public void setLastCodeUpdate(long update) {
|
||||
lastCodeUpdate = update;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the class loader used by this application.
|
||||
*
|
||||
|
@ -264,111 +270,4 @@ public final class TypeManager {
|
|||
return proto;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check a prototype for new or updated resources.
|
||||
*/
|
||||
public void updatePrototype(Prototype proto) {
|
||||
|
||||
synchronized (proto) {
|
||||
// check again because another thread may have checked the
|
||||
// prototype while we were waiting for access to the synchronized section
|
||||
|
||||
boolean updatedResources = false;
|
||||
List createdResources = null;
|
||||
|
||||
// our plan is to do as little as possible, so first check if
|
||||
// anything the prototype knows about has changed on disk
|
||||
for (Iterator i = proto.trackers.values().iterator(); i.hasNext();) {
|
||||
ResourceTracker tracker = (ResourceTracker) i.next();
|
||||
|
||||
try {
|
||||
if (tracker.hasChanged()) {
|
||||
updatedResources = true;
|
||||
tracker.markClean();
|
||||
}
|
||||
} catch (IOException iox) {
|
||||
iox.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
// next we check if files have been created or removed since last update
|
||||
Resource[] resources = proto.getResources();
|
||||
|
||||
for (int i = 0; i < resources.length; i++) {
|
||||
String name = resources[i].getName();
|
||||
if (!proto.trackers.containsKey(name)) {
|
||||
if (name.endsWith(templateExtension) ||
|
||||
name.endsWith(scriptExtension) ||
|
||||
name.endsWith(actionExtension) ||
|
||||
name.endsWith(skinExtension)) {
|
||||
if (createdResources == null) {
|
||||
createdResources = new ArrayList();
|
||||
}
|
||||
|
||||
createdResources.add(resources[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// if nothing needs to be updated, mark prototype as checked and return
|
||||
if (!updatedResources && createdResources == null) {
|
||||
proto.markChecked();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// first go through new files and create new items
|
||||
if (createdResources != null) {
|
||||
Resource[] newResources = new Resource[createdResources.size()];
|
||||
createdResources.toArray(newResources);
|
||||
|
||||
for (int i = 0; i < newResources.length; i++) {
|
||||
String resourceName = newResources[i].getName();
|
||||
if (resourceName.endsWith(templateExtension) ||
|
||||
resourceName.endsWith(scriptExtension) ||
|
||||
resourceName.endsWith(actionExtension)) {
|
||||
try {
|
||||
proto.addCodeResource(newResources[i]);
|
||||
} catch (Throwable x) {
|
||||
app.logEvent("Error updating prototype: " + x);
|
||||
}
|
||||
} else if (resourceName.endsWith(skinExtension)) {
|
||||
try {
|
||||
proto.addSkinResource(newResources[i]);
|
||||
} catch (Throwable x) {
|
||||
app.logEvent("Error updating prototype: " + x);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// next go through existing updatables
|
||||
if (updatedResources) {
|
||||
/*
|
||||
for (Iterator i = updateSet.iterator(); i.hasNext();) {
|
||||
Updatable upd = (Updatable) i.next();
|
||||
|
||||
try {
|
||||
upd.update();
|
||||
} catch (Exception x) {
|
||||
if (upd instanceof DbMapping) {
|
||||
app.logEvent("Error updating db mapping for type " +
|
||||
proto.getName() + ": " + x);
|
||||
} else {
|
||||
app.logEvent("Error updating " + upd + " of prototye type " +
|
||||
proto.getName() + ": " + x);
|
||||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
// mark prototype as checked and updated.
|
||||
proto.markChecked();
|
||||
proto.markUpdated();
|
||||
lastCodeUpdate = proto.lastCodeUpdate();
|
||||
|
||||
} // end of synchronized (proto)
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -376,8 +376,8 @@ public final class RhinoCore implements ScopeProvider {
|
|||
updatePrototype(type.getParentType(), checked);
|
||||
}
|
||||
|
||||
// let the type manager scan the prototype's directory
|
||||
app.typemgr.updatePrototype(type.frameworkProto);
|
||||
// let the prototype check if its resources have changed
|
||||
type.frameworkProto.checkForUpdates();
|
||||
|
||||
// and re-evaluate if necessary
|
||||
if (type.needsUpdate()) {
|
||||
|
@ -428,7 +428,7 @@ public final class RhinoCore implements ScopeProvider {
|
|||
// otherwise, it has already been evaluated for this request by updatePrototypes(),
|
||||
// which is called before a request is handled.
|
||||
if ((type != null) && (type.lastUpdate == -1)) {
|
||||
app.typemgr.updatePrototype(type.frameworkProto);
|
||||
type.frameworkProto.checkForUpdates();
|
||||
|
||||
if (type.needsUpdate()) {
|
||||
evaluatePrototype(type);
|
||||
|
|
Loading…
Add table
Reference in a new issue