Commit 3261e06a authored by Dumoulin Nicolas's avatar Dumoulin Nicolas
Browse files

trunk dir created

parent 6f6eb266
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<!-- ************************************************************* -->
<!-- *** POM Relationships *************************************** -->
<!-- ************************************************************* -->
<groupId>fr.cemagref</groupId>
<artifactId>observation</artifactId>
<version>1.0-SNAPSHOT</version>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.thoughtworks.xstream</groupId>
<artifactId>xstream</artifactId>
<version>1.3.1</version>
</dependency>
<dependency>
<groupId>jfree</groupId>
<artifactId>jfreechart</artifactId>
<version>1.0.13</version>
</dependency>
<dependency>
<groupId>fr.cemagref</groupId>
<artifactId>ohoui</artifactId>
<version>0.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>jfree</groupId>
<artifactId>jcommon</artifactId>
<version>1.0.15</version>
</dependency>
</dependencies>
<!-- ************************************************************* -->
<!-- *** Project Information ************************************* -->
<!-- ************************************************************* -->
<name>${project.artifactId} ${project.version}</name>
<description></description>
<url>http://trac.clermont.cemagref.fr/projets/LISC/wiki/JavaObservation</url>
<licenses>
<license>
<name>GPL</name>
<url>http://www.gnu.org/copyleft/gpl.html</url>
<distribution>repo</distribution>
</license>
</licenses>
<!-- ************************************************************* -->
<!-- *** Build Settings ****************************************** -->
<!-- ************************************************************* -->
<packaging>jar</packaging>
<build>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.6</source>
<target>1.6</target>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<configuration>
<overWriteReleases>false</overWriteReleases>
<overWriteSnapshots>false</overWriteSnapshots>
<overWriteIfNewer>true</overWriteIfNewer>
</configuration>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>copy-dependencies</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
<distributionManagement>
<repository>
<id>trac.clermont.cemagref.fr.nexus</id>
<url>http://trac.clermont.cemagref.fr/nexus/content/repositories/releases</url>
</repository>
<snapshotRepository>
<id>trac.clermont.cemagref.fr.nexus</id>
<url>http://trac.clermont.cemagref.fr/nexus/content/repositories/snapshots</url>
</snapshotRepository>
</distributionManagement>
</project>
package fr.cemagref.observation.gui;
/**
* <code>Configurable</code> This interface is implemented by GUI element that are configurables. (element in a list, panel, ...)
*/
public interface Configurable {
/**
* <code>configure</code> is called when the user want to configure the component.
*
*/
public void configure();
}
package fr.cemagref.observation.gui;
import java.awt.event.ActionListener;
import java.net.URL;
import javax.swing.ImageIcon;
import javax.swing.JButton;
public class ControlsFactory {
public static JButton makeButton(String imageName,
ActionListener listener,
String toolTipText,
String altText) {
// Look for the image.
String imgLocation = "toolbarButtonGraphics/"
+ imageName
+ ".gif";
URL imageURL = ControlsFactory.class.getClassLoader().getResource(imgLocation);
// Create and initialize the button.
JButton button = new JButton();
button.setToolTipText(toolTipText);
button.addActionListener(listener);
if (imageURL != null) {
//image found
button.setIcon(new ImageIcon(imageURL, altText));
} else {
//no image found
button.setText(altText);
System.err.println("Resource not found: " + imgLocation);
}
return button;
}
}
package fr.cemagref.observation.gui;
import javax.swing.JComponent;
/**
* <code>Drawable</code> A component implements this interface if it could be graphically drawed as a JComponent.
*/
public interface Drawable {
/**
* <code>getTitle</code>
*
* @return The title of this component.
*/
public String getTitle();
public JComponent getDisplay();
}
package fr.cemagref.observation.gui;
import javax.swing.JFrame;
/**
* <code>ObserversManagerHandler</code> is those who handles the ObservableManager.
*/
public interface ObserversManagerHandler {
/**
* <code>getHandlingFrame</code> is used by dialog box to know which is the parent frame.
*/
public JFrame getHandlingFrame();
public void showDrawable(Drawable drawable);
}
package fr.cemagref.observation.gui;
import fr.cemagref.observation.kernel.ObservableManager;
import fr.cemagref.observation.kernel.ObservableManager.ClassAndObserver;
import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.HashSet;
import javax.swing.JButton;
import javax.swing.JList;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JToolBar;
import javax.swing.ListSelectionModel;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
@SuppressWarnings("serial")
public class ObserversManagerPanel extends JPanel implements ListSelectionListener {
private ObserversManagerHandler observersManagerHandler;
private JList list;
private JButton removeButton;
private JButton confButton;
private JButton showButton;
private HashSet<ClassAndObserver> observersShowed = new HashSet<ClassAndObserver>();
public ObserversManagerPanel(ObserversManagerHandler observersManagerHandler) {
super();
this.observersManagerHandler = observersManagerHandler;
this.setLayout(new BorderLayout());
// The list
list = new JList(ObservableManager.getObservableManager());
list.setSelectionMode(ListSelectionModel.SINGLE_INTERVAL_SELECTION);
list.setLayoutOrientation(JList.HORIZONTAL_WRAP);
list.addListSelectionListener(this);
JScrollPane listScroller = new JScrollPane(list);
this.add(listScroller,BorderLayout.CENTER);
// The toolbar
JToolBar toolBar = new JToolBar();
toolBar.setFloatable(false);
add(toolBar,BorderLayout.PAGE_END);
// The "remove" button
removeButton = ControlsFactory.makeButton("general/Delete24",new RemoveButtonListener(),"Remove the selected module","Remove");
toolBar.add(removeButton);
// The "conf" button
confButton = ControlsFactory.makeButton("general/Edit24",new ConfButtonListener(),"Configure the selected module","Configure");
toolBar.add(confButton);
// The "show" button
showButton = ControlsFactory.makeButton("general/Find24",new ShowButtonListener(),"Show the selected module","Show");
toolBar.add(showButton);
// set buttons enabled or not
this.valueChanged(null);
}
public void valueChanged(ListSelectionEvent e) {
if (list.getSelectedIndex()>=0) {
ClassAndObserver classAndObserver = (ClassAndObserver)list.getSelectedValue();
removeButton.setEnabled(true);
confButton.setEnabled(classAndObserver.getObserver() instanceof Configurable);
showButton.setEnabled(
// observers must be drawable
classAndObserver.getObserver() instanceof Drawable
// and observers must not be yet displayed
&& !observersShowed.contains(classAndObserver)
);
} else {
removeButton.setEnabled(false);
confButton.setEnabled(false);
showButton.setEnabled(false);
}
}
private class RemoveButtonListener implements ActionListener {
public void actionPerformed(ActionEvent e) {
if (JOptionPane.showConfirmDialog(observersManagerHandler.getHandlingFrame(),"Sure ?","Confirmation",JOptionPane.YES_NO_OPTION)==0) {
ClassAndObserver item = (ClassAndObserver)list.getSelectedValue();
ObservableManager.removeObserverListener(item.getType(),item.getObserver());
}
}
}
private class ConfButtonListener implements ActionListener {
public void actionPerformed(ActionEvent e) {
((Configurable)((ClassAndObserver)list.getSelectedValue()).getObserver()).configure();
}
}
private class ShowButtonListener implements ActionListener {
public void actionPerformed(ActionEvent e) {
ClassAndObserver classAndObserver = (ClassAndObserver)list.getSelectedValue();
if (observersShowed.add(classAndObserver)) {
// force buttons enabling refresh
valueChanged(null);
// get display and add it in handler
observersManagerHandler.showDrawable((Drawable)classAndObserver.getObserver());
}
}
}
}
/**
* L'interface "annotation" pour marquer les observables.
*/
package fr.cemagref.observation.kernel;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* <code>Observable</code> The annotation used to declare a field as observable
*/
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.FIELD, ElementType.METHOD})
public @interface Observable {
/**
* <code>description</code> is the textual description of the observable.
*
* @return the textual description of the observable.
*/
String description();
}
package fr.cemagref.observation.kernel;
import java.io.Reader;
import java.util.ArrayList;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import javax.swing.ListModel;
import javax.swing.event.ListDataEvent;
import javax.swing.event.ListDataListener;
import com.thoughtworks.xstream.XStream;
import com.thoughtworks.xstream.io.xml.DomDriver;
/**
* TODO traduce in english
*/
public class ObservableManager implements ListModel {
private static ObservableManager om = null;
private Map<Class, ObservablesHandler> observables;
private List<ListDataListener> listDataListeners = new ArrayList<ListDataListener>();
/** Le constructeur. Il est private, car l'accès à l'observable manager doit
* se faire exclusivement via la méthode statique getObservableManager().
*/
private ObservableManager() {
observables = new Hashtable<Class,ObservablesHandler>();
}
/**
* The true mean to access Observable manager.
*
* @return L'observable manager du système.
*/
public static ObservableManager getObservableManager() {
return om == null ? om = new ObservableManager() : om;
}
/**
* clear method clears all class-observers associations
*/
public static void clear() {
for (ObservablesHandler co : om.observables.values()) {
co.clearObservers();
}
om.fireObservableManagerStructureChanged();
}
/**
* Déclare une classe comme étant observable.
*
* Si une classe a déjà été déclarée comme observable,
* l'appel de cette méthode est équvalent à un getObservable(Class).
*
* @param cl La classe déclarée comme observable
* @return Le ClassObservable de cl.
*/
public static ObservablesHandler addObservable(Class cl) {
if (getObservableManager().observables.containsKey(cl)) {
return getObservableManager().observables.get(cl);
}
ObservablesHandler co = new ObservablesHandler(cl);
getObservableManager().observables.put(cl, co);
getObservableManager().fireObservableManagerStructureChanged();
return co;
}
/** Permet d'obtenir l'instance de ClassObservable associée à la classe
* donnée en argument.
*
* PERFS : Les classObservable sont stockées dans une Hashtable,
* avec une clé sur Class, c'est à dire que l'algo est de l'ordre
* de N log(N) (où N est le nombre d'observables), avec
* (ce qui n'est pas négligeable), une opération de base qui est Class.equals(Object).
* En conclusion : pour une utilisation très intensive, on gardera une variable
* pointant sur le ClassObservable, pour éviter d'appeler trop souvent cette méthode.
*
* @param cl La classe dont on veut le ClassObservable
* @return Le classObservable, ou null si la classe donnée en argument
* n'a pas été déclarée comme étant observable.
*/
public static ObservablesHandler getObservable(Class cl) {
return getObservableManager().observables.get(cl);
}
/** Ajoute un ObserverListener à la liste.
*
* @param ob L'ObserverListener à ajouter.
*/
public static ObserverListener addObserverListener(Class cl, ObserverListener ob) {
ObserverListener observerListener = addObservable(cl).addObserverListener(ob);
getObservableManager().fireObservableManagerStructureChanged();
return observerListener;
}
/** Retire un seul observerListener de la liste. Renvoie true s'il a effectivement été trouvé
* et retiré.
* @param ob L'ObserverListener à retirer.
* @return
*/
public static boolean removeObserverListener(Class cl, ObserverListener ob) {
boolean response = getObservable(cl).removeObserverListener(ob);
getObservableManager().fireObservableManagerStructureChanged();
return response;
}
public static void initObservers() {
for (ObservablesHandler classObservable : getObservableManager().observables.values()) {
for (ObserverListener observer : classObservable.getObservers()) {
observer.init();
}
}
}
public static void closeObservers() {
for (ObservablesHandler classObservable : getObservables().values()) {
for (ObserverListener observer : classObservable.getObservers()) {
observer.close();
}
}
}
public static Map<Class, ObservablesHandler> getObservables() {
return getObservableManager().observables;
}
public static void setObservers(Reader observablesReader, XStream xstream) {
Map<Class,ObservablesHandler> observablesReaded = (Map<Class,ObservablesHandler>) xstream.fromXML(observablesReader);
for (Map.Entry<Class,ObservablesHandler> entry : observablesReaded.entrySet()) {
// add to the list of observers those readed from the file
ObservablesHandler clObservable = addObservable(entry.getKey());
for (ObserverListener observer : entry.getValue().getObservers()) {
// use addObserverListener method garanties safe init
clObservable.addObserverListener(observer);
}
}
}
public static void setObservers(Reader observablesReader) {
setObservers(observablesReader, new XStream(new DomDriver()));
}
/**
* @see javax.swing.ListModel#getSize()
*/
public int getSize() {
int size = 0;
for (ObservablesHandler classObservable : observables.values()) {
size += classObservable.getObserversCount();
}
return size;
}
/**
* @see javax.swing.ListModel#getElementAt(int)
*/
public Object getElementAt(int index) {
Set<Map.Entry<Class, ObservablesHandler>> entrySet = observables.entrySet();
Iterator<Map.Entry<Class, ObservablesHandler>> iterator = entrySet.iterator();
Map.Entry<Class, ObservablesHandler> current = iterator.next();
int count = current.getValue().getObserversCount();
while (count <= 0) {
current = iterator.next();
count = current.getValue().getObserversCount();
}
while (count <= index) {
current = iterator.next();
count += current.getValue().getObserversCount();
}
int realIndex = index - (count - current.getValue().getObserversCount());
assert realIndex < current.getValue().getObserversCount() : realIndex + " !< " + current.getValue().getObserversCount();
return new ClassAndObserver(current.getKey(), current.getValue().getObserver(realIndex));
}
/**
* @see javax.swing.ListModel#addListDataListener(javax.swing.event.ListDataListener)
*/
public void addListDataListener(ListDataListener l) {
listDataListeners.add(l);
}
/**
* @see javax.swing.ListModel#removeListDataListener(javax.swing.event.ListDataListener)
*/
public void removeListDataListener(ListDataListener l) {
listDataListeners.remove(l);
}
void fireObservableManagerStructureChanged() {
for (ListDataListener listDataListener : listDataListeners) {
listDataListener.contentsChanged(new ListDataEvent(this, ListDataEvent.CONTENTS_CHANGED, 0, getSize()));
}
}
public static class ClassAndObserver {
private Class type;
private ObserverListener observer;
public ClassAndObserver(Class type, ObserverListener observer) {
this.type = type;
this.observer = observer;
}
public Class getType() {
return type;
}
public ObserverListener getObserver() {
return observer;
}
public String toString() {
return observer.getClass().getSimpleName() + " -> " + type.getSimpleName();
}
/**
* @see java.lang.Object#equals(java.lang.Object)
*/
@Override
public boolean equals(Object obj) {
return obj.hashCode() == this.hashCode();
}
/**
* @see java.lang.Object#hashCode()
*/
@Override
public int hashCode() {
return type.hashCode() + observer.hashCode();
}
}
}
package fr.cemagref.observation.kernel;
import java.lang.reflect.AccessibleObject;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
// TODO troduce in english
public class ObservablesHandler {
private java.util.ArrayList<ObserverListener> observers;
private transient ObservableFetcher[] fetchers;
/**
* Constructeur.
*
* @param cl La classe à laquelle on associe le présent ClassObservable
*/
public ObservablesHandler(Class cl) {