alvinalexander.com | career | drupal | java | mac | mysql | perl | scala | uml | unix  

What this is

This file is included in the DevDaily.com "Java Source Code Warehouse" project. The intent of this project is to help you "Learn Java by Example" TM.

Other links

The source code

/*
 *                 Sun Public License Notice
 * 
 * The contents of this file are subject to the Sun Public License
 * Version 1.0 (the "License"). You may not use this file except in
 * compliance with the License. A copy of the License is available at
 * http://www.sun.com/
 * 
 * The Original Code is NetBeans. The Initial Developer of the Original
 * Code is Sun Microsystems, Inc. Portions Copyright 1997-2001 Sun
 * Microsystems, Inc. All Rights Reserved.
 */

package org.netbeans.modules.schema2beans;

import java.util.*;

import java.beans.*;

/**
 *  The intent of this class is to provide a schema2beans graph registry,
 *  where the graphs are stored by unique name and type. Combined with
 *  the DDRegistryParser, the DDRegistry provides a sort of meta-schema2beans
 *  graph where we can ask for all the graphs of one type and ask for a 
 *  parser on any set of graphs. These are the two main goals of this class.
 *
 *    1. provide a common and central place where we can keep track 
 *       of all the graphs that we have created. Naming the graphs by 
 *       unique name and type allows to get either one specific graph 
 *       or a set of graphs.
 *
 *    2. provide a meta-schema2beans graph view for parsing any set of graphs. 
 *       For example, to get a parser on all the graphs of type 'ejb' 
 *       (assuming we registered graphs of this type).
 *
 *  Therefore, this class provides two kind of methods: to add/remove graphs
 *  to the registry and to create a DDRegistry parser. A DDRegistryParser is
 *  an Iterator that returns all the elements described a schema2beans tree path. 
 *
 *  The registry also provides a convenient class (DDChangeMarker) that helps
 *  keeping track of any change.
 */
public class DDRegistry extends Object {
    
    /**
     *	The goal of this class is to provide a simple way to know if a graph
     *	or a set of graphs had their content changed. The ChangeMarker can
     *	be used to implemenent a cache mechanism, in order to avoid parsing
     *	the graphs if nothing in the graph changed since the last parsing.
     *
     *	A ChangeMarker is created by the registry, ddReg.newChangeMarker().
     *	We can add to the changeMarger a BaseBean graph, a Cursor or another
     *	ChangeMarker. So, ChangeMarker can be nested, and any modification in
     *	a nested ChangeMarker would need that the upper ChangeMarker have been
     *  been modified.
     */
    public static class DDChangeMarker {
	
	private DDRegistry reg;
	private long timestamp;
	
	private ArrayList elts = null;
	
	DDChangeMarker(DDRegistry reg) {
	    this.reg = reg;
	    this.elts = new ArrayList();
	    this.timestamp = 0L;
	}
	
	
	public int size() {
	    return this.elts.size();
	}
	
	/**
	 *  If any graph of the added marker change, the current marker is
	 *  also considered changed.
	 */
	public void add(DDChangeMarker cm) {
	    if (cm == this) {
		Thread.dumpStack();
	    }
	    this.elts.add(cm);
	}
	
	/**
	 *  Add a graph to the marker list. If any change occurs in this graph
	 *  after resetMarker() is called, hasChanged() would return true.
	 */
	public void add(BaseBean b) {
	    RegEntry re = this.reg.getRegEntry(b, false);
	    if (re != null && !this.elts.contains(re)) {
		this.elts.add(re);
	    }
	}
	
	/**
	 *  Add the graph the cursor belongs to, to the marker list
	 */
	public void add(DDRegistryParser.DDCursor c) {
	    String id = this.reg.getID(c);
	    if (id != null) {
		BaseBean b = this.reg.getRoot(id);
		this.add(b);
	    }
	}
	
	/**
	 *  removal methods.
	 */
	public void remove(DDChangeMarker cm) {
	    this.elts.remove(cm);
	}
	
	public void remove(BaseBean b) {
	    RegEntry re = this.reg.getRegEntry(b, false);
	    if (re != null)
		this.elts.remove(re);
	}
	
	public void remove(DDRegistryParser.DDCursor c) {
	    String id = this.reg.getID(c);
	    if (id != null) {
		BaseBean b = this.reg.getRoot(id);
		this.remove(b);
	    }
	}

	/**
	 *  Reset the marke change time. Any change that happened before now
	 *  are ignored.
	 */
	public void resetTime() {
	    this.timestamp = System.currentTimeMillis();
	}
	
	/**
	 *  Return true if a change event happen between the last resetTime
	 *  and now.
	 */
	public boolean hasChanged() {
	    boolean b = this.hasChanged(this.timestamp);
	    return b;
	}
	
	private boolean hasChanged(long ts) {
	    for(int i=0; i ts) {
			    return true;
			}
		    }
	    }
	    return false;
	}

	/**
	 *  Dump all the registered markers
	 */
	public String dump() {
	    return this.dump(new StringBuffer(), "",	// NOI18N
			     this.timestamp).toString();
	}
	
	public StringBuffer dump(StringBuffer sb, String indent, long ts) {	// BEGIN_NOI18N
	    
	    sb.append(indent + this.toString() + "\n");
	    
	    for(int i=0; i ts) {
			    sb.append(" Changed  (bean ts:" + l 
				      + " > cm ts:" + ts );
			    //    + ") - last event: " + re.getLastEvent());
			} else {
			    sb.append(" No_Change (bean ts:" + l 
				      + " < cm ts:" + ts + ")");
			}
			sb.append("\n");
		    }
	    }
	    return sb;
	}									// END_NOI18N
	
	public String toString() {
	    return "DDChangeMarker-0x" + Integer.toHexString(this.hashCode());	// NOI18N
	}
    }
    
    /*
     *	Change event listener used by the change marker class
     */
    public class ChangeTracer implements PropertyChangeListener {
	DDRegistry 	reg;
	
	public ChangeTracer(DDRegistry reg) {
	    this.reg = reg;
	}
	
	public void propertyChange(PropertyChangeEvent e) {
	    
	    try {
		BaseBean s = (BaseBean)e.getSource();
		RegEntry re = this.reg.getRegEntry(s, false);
		re.setTimestamp();
		//String trc = 
		//    s.graphManager().getKeyPropertyName(e.getPropertyName());
		//re.setLastEvent(trc);
	    } catch(Exception ex) {
	    }
	}
    }
    
    private ArrayList		scopes;
    private ChangeTracer 	changeTracer;


    //
    public DDRegistry() {
	this.scopes = new ArrayList();
	this.changeTracer = new ChangeTracer(this);
    }
    
    /**
     *  Create a new entry in the DD graph registry. The schema2beans graph
     *  bean is added to registry using a unique name (ID), such as a unique
     *  internal identifier, and a non unique name (name), 
     *  such as a display name.
     *  
     *  Any number of non unique type can also be associated to a graph
     *  entry, see the method addType.
     *
     */
    public void createEntry(BaseBean bean, String ID, String name) {
	RegEntry entry = this.getRegEntry(bean, false);
	if (entry != null) {
	    throw new IllegalArgumentException(Common.getMessage(
	    "BeanGraphAlreadyInRegistry_msg", bean.name()));
	}
	
	entry = this.getRegEntry(ID);
	if (entry != null) {
	    throw new IllegalArgumentException(Common.getMessage(
	    "CantRegisterGraphSameID_msg", bean.name(), entry, ID));
	}
	bean.addPropertyChangeListener(this.changeTracer);
	this.scopes.add(new RegEntry(bean, ID, name));
    }

    /**
     *	Change the schema2beans graph for the unique entry ID. This method
     *  might be used if another graph should replace an existing entry.
     */
    public void updateEntry(String ID, BaseBean bean) {
	RegEntry entry = this.getRegEntry(ID);
	if (entry != null)
	    entry.setBean(bean);
	else
	    throw new IllegalArgumentException(Common.getMessage(
	    "CantUpdateGraphNotInRegistry_msg", ID));
    }
    
    /**
     *	Remove an entry in the registry.
     */
    public void removeEntry(BaseBean bean) {
	RegEntry entry = this.getRegEntry(bean, false);
	if (entry != null) {
	    entry.getBean().removePropertyChangeListener(this.changeTracer);
	    this.removeRegEntry(entry);
	}
    }
    
    /**
     *  Rename a graph entry unique ID to a new unique ID entry and new
     *  non unique name.
     */
    public void renameEntry(String oldID, String newID, String newName) {
	RegEntry entry = this.getRegEntry(oldID);
	if (entry != null) {
	    entry.setID(newID);
	    if (newName != null)
		entry.setName(newName);
	}
    }

    /**
     *  Rename a graph unique ID to a new unique ID.
     */
    public void renameEntry(String oldID, String newID) {
	this.renameEntry(oldID, newID, null);
    }

    /**
     *  Remove a registry entry.
     */
    public void removeEntry(String ID) {
	RegEntry entry = this.getRegEntry(ID);
	if (entry != null)
	    entry.getBean().removePropertyChangeListener(this.changeTracer);
	this.removeRegEntry(entry);
    }
    
    /**
     *  This return a new change marker instance, that can be used to know
     *  if any graph of the registry has changed.
     */	
    public DDChangeMarker createChangeMarker() {
	return new DDChangeMarker(this);
    }
    
    /**
     *	Return true of the specified schema2beans graph is registered with the
     *  specified type.
     */
    public boolean hasType(BaseBean bean, String type) {
	RegEntry r = this.getRegEntry(bean, false);
	if (r != null)
	    return r.hasType(type);
	return false;
    }
    
    /**
     *  Reset the change timestamp of all the registered graphs.
     */
    public void clearCache() {
	for (int i=0; i0)
	    return r[0];
	return null;
    }
    
    /**
     *	Return all the bean roots for this name (either unique name or scope)
     */
    public BaseBean[] getRoots(String s) {
	s = getGraphName(s);
	//	Try to get the root by name, then by type
	RegEntry se = this.getRegEntry(s);
	if (se == null) {
	    ArrayList list = new ArrayList();
	    for (int i=0; i
... this post is sponsored by my books ...

#1 New Release!

FP Best Seller

 

new blog posts

 

Copyright 1998-2021 Alvin Alexander, alvinalexander.com
All Rights Reserved.

A percentage of advertising revenue from
pages under the /java/jwarehouse URI on this website is
paid back to open source projects.