org.netbeans.modules.schema2beans.DDRegistry Maven / Gradle / Ivy
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
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
© 2015 - 2025 Weber Informatics LLC | Privacy Policy