public ResourceChangeSet diffResource(String file,
byte[] ob,
byte[] cb) {
ResourceChangeSet pkgcs = new ResourceChangeSet( file, ChangeType.UPDATED );
ResourceType type = ResourceType.determineResourceType( file );
if( ResourceType.DRL.equals( type ) || ResourceType.GDRL.equals( type ) || ResourceType.RDRL.equals( type )) {
try {
PackageDescr opkg = new DrlParser().parse( new ByteArrayResource( ob ) );
PackageDescr cpkg = new DrlParser().parse( new ByteArrayResource( cb ) );
List<RuleDescr> orules = new ArrayList<RuleDescr>( opkg.getRules() ); // needs to be cloned
List<RuleDescr> crules = cpkg.getRules();
for( RuleDescr crd : crules ) {
pkgcs.getLoadOrder().add(new ResourceChangeSet.RuleLoadOrder(cpkg.getName(), crd.getName(), crd.getLoadOrder() ) );
// unfortunately have to iterate search for a rule with the same name
boolean found = false;
for( Iterator<RuleDescr> it = orules.iterator(); it.hasNext(); ) {
RuleDescr ord = it.next();
if( ord.getName().equals( crd.getName() ) ) {
found = true;
it.remove();
// using byte[] comparison because using the descriptor equals() method
// is brittle and heavier than iterating an array
if( !segmentEquals(ob, ord.getStartCharacter(), ord.getEndCharacter(),
cb, crd.getStartCharacter(), crd.getEndCharacter() ) ) {
pkgcs.getChanges().add( new ResourceChange( ChangeType.UPDATED,
ResourceChange.Type.RULE,
crd.getName() ) );
}
break;
}
}
if( !found ) {
pkgcs.getChanges().add( new ResourceChange( ChangeType.ADDED,
ResourceChange.Type.RULE,
crd.getName() ) );
}
}
for( RuleDescr ord : orules ) {
pkgcs.getChanges().add( new ResourceChange( ChangeType.REMOVED,
ResourceChange.Type.RULE,
ord.getName() ) );
}
} catch ( Exception e ) {
logger.error( "Error analyzing the contents of "+file+". Skipping.", e );
}
}
Collections.sort( pkgcs.getChanges(), new Comparator<ResourceChange>() {
public int compare(ResourceChange o1,
ResourceChange o2) {
return o1.getChangeType().ordinal() - o2.getChangeType().ordinal();
}
} );