KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > buchuki > ensmer > Backhoe


1 /*
2  * Copyright 2004 Dusty Phillips
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */

16 package com.buchuki.ensmer;
17
18 import java.io.*;
19 import java.util.*;
20 import javax.swing.event.ChangeEvent JavaDoc;
21 import javax.swing.event.ChangeListener JavaDoc;
22 import com.buchuki.ensmer.object.*;
23 import com.buchuki.ensmer.prevayler.queries.*;
24 import groovy.lang.*;
25 import java.lang.reflect.Constructor JavaDoc;
26 import org.prevayler.*;
27
28 /**
29  * Class to manage both sides of objects -- Frontends and Backends. The
30  * Backhoe is responsible for determining what kinds of objects are available
31  * (specifically, what objects that it is possible to load both a frontend
32  * and a backend for), for loading serialized objects on startup, for loading
33  * new objects at run time, and for serializing the objects as they are
34  * created.
35  *
36  * @author Dusty Phillips [dusty@buchuki.com]
37  */

38 public class Backhoe {
39
40     /**
41      * Construct the Backhoe. Retrieve all prevayled objects and assign them to
42      * their respective areas. Load all frontend classes that have associated
43      * backends.
44      */

45     public Backhoe() {
46         File frontends = EnsmerManager.instance().
47                 getConfigManager().getSettingsDirectory("frontends");
48         PackagePaths pathFinder = new PackagePaths(frontends, ".groovy");
49         try {
50             classMap = pathFinder.getValidClassFileMap(Class.forName("com.buchuki.ensmer.object.Backend"));
51         } catch (Exception JavaDoc e) {
52             e.printStackTrace();
53         }
54     }
55
56     /**
57      * Load a Frontend object for a specific backend and return it
58      *
59      * @param backend The backend to create a frontend for
60      * @return The frontend for the specific backend
61      * @throws Exception if the Frontend cannot be instantiated
62      */

63     public Frontend loadFrontend(Backend backend) throws Exception JavaDoc {
64         GroovyClassLoader gcl = new GroovyClassLoader();
65         File file = classMap.get(backend.getClass());
66         Class JavaDoc feClass = gcl.parseClass(file);
67         Frontend frontend = (Frontend) feClass.newInstance();
68         frontend.setBackend(backend);
69         backend.addChangeListener(frontend);
70         backend.addChangeListener(new StoreChangesListener());
71         return frontend;
72     }
73
74     /**
75      * Instantiate a Backend object given an identifier in the Prevayler.
76      * Instantiates the class and sets up the data and id. This method should
77      * be called when instantiating a new Backend for a previously prevayled
78      * object. This method is generally called internally by Ensmer, and is
79      * not usually needed by third party objects. Compare to findBackend(Long id).
80      *
81      * @param id the identifier of the backend to be instantiated
82      * @return an instantiated backend for the id
83      * @throws Exception if the backend cannot be instantiated
84      * @see #findBackend(Long id)
85      */

86     public Backend getBackend(Long JavaDoc id) throws Exception JavaDoc {
87         Prevayler prevayler = EnsmerManager.instance().getPrevayler();
88         Class JavaDoc backendClass = (Class JavaDoc) prevayler.execute(new GetObjectBackendClassQuery(id));
89         Constructor JavaDoc constructor = backendClass.getConstructor(Class.forName("java.io.Serializable"));
90         Serializable sel = (Serializable) prevayler.execute(new GetObjectDataQuery(id));
91         Backend backend = (Backend) constructor.newInstance(sel);
92         backend.setId(id);
93         return backend;
94     }
95     
96     /**
97      * Convenience method to find a Backend in any Area given an Identifier. This
98      * method should be called when the backend has already been instantiated and
99      * you want to get a reference to it. This method may be called by third party objects
100      * that serialize the identifier of an object and need to have a reference to
101      * the other object that has already been instantiated. Compare to getBackend(Long id).
102      *
103      * @param id the identifier of the backend to be discovered
104      * @return the instantiated backend for the ID or null if the object doesn't exist
105      * @see #getBackend(Long id)
106      * @since Ensmer 0.1+milestone-4
107      */

108     public Backend findBackend(Long JavaDoc id) {
109         AreaManager areaMan = EnsmerManager.instance().getAreaManager();
110         Long JavaDoc areaID = areaMan.getAreaIDForObject(id);
111         if (areaID == null) {
112             return null;
113         }
114         Area area = areaMan.getArea(areaID);
115         return area.getFrontend(id).getBackend();
116     }
117
118     /**
119      * Get a list of Class objects for which valid frontends can exist.
120      * @return a List of class objects for which frontends can be loaded
121      */

122     public Set<Class JavaDoc<? extends Backend>> getBackendClasses() {
123         return classMap.keySet();
124     }
125
126     /**
127      * Map of class to file objects where the keys are subclasses of Backend,
128      * and the values are files pointing to groovy scripts.
129      */

130     private Map<Class JavaDoc<? extends Backend>, File> classMap;
131 }
132
133 /**
134  * Change listener to serialize changes every time the data is updated in a
135  * backend.
136  *
137  * @author Dusty Phillips [dusty@buchuki.com]
138  */

139 class StoreChangesListener implements ChangeListener JavaDoc {
140     /**
141      * Notification that the data has changed in the backend and needs to be
142      * serialized, so serialize it.
143      *
144      * @param event the event generated
145      */

146     public void stateChanged(ChangeEvent JavaDoc event) {
147         Backend backend = (Backend) event.getSource();
148         Prevayler prevayler = EnsmerManager.instance().getPrevayler();
149         try {
150             prevayler.execute(new SetObjectDataTransaction(backend.getId(),
151                 backend.getSerializable()));
152         } catch (Exception JavaDoc e) {
153             e.printStackTrace();
154         }
155     }
156 }
157
158
Popular Tags