001: package org.apache.ojb.broker;
002:
003: import java.util.Collection;
004: import java.util.Iterator;
005: import java.util.Vector;
006:
007: import org.apache.ojb.broker.query.Query;
008: import org.apache.ojb.broker.query.QueryFactory;
009: import org.apache.ojb.junit.PBTestCase;
010:
011: /**
012: * Demo Application that shows basic concepts for Applications using the PersistenceBroker
013: * as a mediator for persistence
014: */
015: public class ProxyExamples extends PBTestCase {
016: public static void main(String[] args) {
017: String[] arr = { ProxyExamples.class.getName() };
018: junit.textui.TestRunner.main(arr);
019: }
020:
021: public ProxyExamples(String name) {
022: super (name);
023: }
024:
025: /**
026: * This example shows how the PersistenceBroker can be used with a highly configurable proxy concept.
027: * The main idea is, not to return materialized objects but rather lazy proxies, that defer materialization
028: * until it is definitely neccesary (e.g. reading an Objects attribute).
029: * <p/>
030: * To achieve such a behaviour, you can define proxies for each persistent class.
031: * As an example see the Repository.xml file in this examples directory.
032: * <p/>
033: * It is not always the best option to use lazy materialization. The usage of proxies can be completely configured
034: * in the xml repository. That is, if you decide not to use proxies, you don't have to change program-code,
035: * but only out-comment the corresponding entry in the repos
036: * itory.
037: */
038: public void testProgrammedProxies() throws Exception {
039: String name = "testDynamicProxies_"
040: + System.currentTimeMillis();
041: Vector myArticles = new Vector();
042: // In the following code we will generate 10 Proxy-objects.
043: ProductGroup pg = new ProductGroup();
044: pg.setGroupName(name);
045: broker.beginTransaction();
046: broker.store(pg);
047: broker.commitTransaction();
048:
049: for (int i = 1; i < 10; i++) {
050: Article a = new Article();
051: a.setArticleName(name);
052: a.setProductGroup(pg);
053: broker.beginTransaction();
054: broker.store(a);
055: broker.commitTransaction();
056: Identity id = broker.serviceIdentity().buildIdentity(a);
057: InterfaceArticle A = (InterfaceArticle) ((PersistenceBrokerInternal) broker)
058: .createProxy(Article.class, id);
059: myArticles.add(A);
060: //System.out.println(A);
061: }
062: // In the following code we call methods that reference the real subjects attributes.
063: // To access an articles name as in getArticleName(), the proxy object has to materialze the real subjects from db.
064: // but note: the references to an Articles productgroup are not materialized immediately,
065: // but contain proxy objects, representing ProductGroups.
066: for (int i = 0; i < 9; i++) {
067: InterfaceArticle a = (InterfaceArticle) myArticles.get(i);
068: //System.out.println("Article[" + a.getArticleId() + "] : " + a.getArticleName());
069: assertNotNull(a);
070: }
071: // In the following code we will access the real ProductGroup objects.
072: // thus the Proxies have to materialize them.
073: for (int i = 0; i < 9; i++) {
074: InterfaceArticle a = (InterfaceArticle) myArticles.get(i);
075: assertNotNull(a.getProductGroup());
076: assertNotNull(a.getProductGroup().getName());
077:
078: //System.out.println("Article[" + a.getArticleId() + "] is in group " + a.getProductGroup().getName());
079: }
080: // in the following code we will touch fields of the ProductGroup references.
081: // Now proxies in the AllArticlesInGroup collection need to be materialized
082: //System.out.println("now playing with product group no. 2");
083: Object[] pkvals = new Object[1];
084: pkvals[0] = new Integer(2);
085: Identity id = new Identity(ProductGroup.class,
086: ProductGroup.class, pkvals);
087: InterfaceProductGroup group2 = null;
088: try {
089: group2 = (InterfaceProductGroup) ((PersistenceBrokerInternal) broker)
090: .createProxy(ProductGroupProxy.class, id);
091: } catch (Exception ignored) {
092: }
093: //System.out.println(group2.toString());
094: broker.beginTransaction();
095: for (int i = 0; i < group2.getAllArticles().size(); i++) {
096: InterfaceArticle a = (InterfaceArticle) group2
097: .getAllArticles().get(i);
098: //System.out.println(a.getArticleName());
099: assertNotNull(a);
100: broker.store(a);
101: }
102: broker.store(group2);
103: broker.commitTransaction();
104: }
105:
106: // private Class getDynamicProxyClass(Class clazz)
107: // {
108: // try
109: // {
110: // Class[] interfaces = clazz.getInterfaces();
111: // Class proxyClass = Proxy.getProxyClass(clazz.getClassLoader(), interfaces);
112: // return proxyClass;
113: // }
114: // catch(Throwable t)
115: // {
116: // System.out.println("OJB Warning: can not use dynamic proxy for class " + clazz.getName() + ": " + t.getMessage());
117: // return null;
118: // }
119: //
120: // }
121:
122: /**
123: * This example shows how the PersistenceBroker can be used with a highly configurable proxy concept.
124: * The main idea is, not to return materialized objects but rather lazy proxies, that defer materialization
125: * until it is definitely neccesary (e.g. reading an Objects attribute).
126: * <p/>
127: * To achieve such a behaviour, you can define proxies for each persistent class.
128: * As an example see the Repository.xml file in this examples directory.
129: * <p/>
130: * It is not always the best option to use lazy materialization. The usage of proxies can be completely configured
131: * in the xml repository. That is, if you decide not to use proxies, you don't have to change program-code,
132: * but only out-comment the corresponding entry in the repos
133: * itory.
134: */
135: public void testDynamicProxies() {
136: String name = "testDynamicProxies_"
137: + System.currentTimeMillis();
138: Vector myArticles = new Vector();
139: // In the following code we will generate 10 Proxy-objects.
140: ProductGroup pg = new ProductGroup();
141: pg.setGroupName(name);
142: broker.beginTransaction();
143: broker.store(pg);
144: broker.commitTransaction();
145:
146: for (int i = 1; i < 10; i++) {
147: Article a = new Article();
148: a.setArticleName(name);
149: a.setProductGroup(pg);
150: broker.beginTransaction();
151: broker.store(a);
152: broker.commitTransaction();
153: Identity id = broker.serviceIdentity().buildIdentity(a);
154: InterfaceArticle A = (InterfaceArticle) ((PersistenceBrokerInternal) broker)
155: .createProxy(Article.class, id);
156: myArticles.add(A);
157: //System.out.println(A);
158: }
159: // In the following code we call methods that reference the real subjects attributes.
160: // To access an articles name as in getArticleName(), the proxy object has to materialze the real subjects from db.
161: // but note: the references to an Articles productgroup are not materialized immediately,
162: // but contain proxy objects, representing ProductGroups.
163: for (int i = 0; i < 9; i++) {
164: InterfaceArticle a = (InterfaceArticle) myArticles.get(i);
165: //System.out.println("Article[" + a.getArticleId() + "] : " + a.getArticleName());
166: }
167: // In the following code we will access the real ProductGroup objects.
168: // thus the Proxies have to materialize them.
169: for (int i = 0; i < 9; i++) {
170: InterfaceArticle a = (InterfaceArticle) myArticles.get(i);
171: //System.out.println("Article[" + a.getArticleId() + "] is in group " + a.getProductGroup().getName());
172: }
173: }
174:
175: public void testCollectionProxies() throws Exception {
176: ProductGroupWithCollectionProxy org_pg = new ProductGroupWithCollectionProxy();
177: org_pg.setId(new Integer(7));
178: Identity pgOID = broker.serviceIdentity().buildIdentity(org_pg);
179:
180: ProductGroupWithCollectionProxy pg = (ProductGroupWithCollectionProxy) broker
181: .getObjectByIdentity(pgOID);
182: assertEquals(org_pg.getId(), pg.getId());
183:
184: Collection col = pg.getAllArticles();
185: int countedSize = col.size(); // force count query
186: Iterator iter = col.iterator();
187: while (iter.hasNext()) {
188: InterfaceArticle a = (InterfaceArticle) iter.next();
189: }
190:
191: assertEquals("compare counted and loaded size", countedSize,
192: col.size());
193: }
194:
195: public void testCollectionProxiesAndExtents() throws Exception {
196: ProductGroupWithCollectionProxy pg = new ProductGroupWithCollectionProxy();
197: pg.setId(new Integer(5));
198: Identity pgOID = broker.serviceIdentity().buildIdentity(pg);
199:
200: pg = (ProductGroupWithCollectionProxy) broker
201: .getObjectByIdentity(pgOID);
202: assertEquals(5, pg.getId().intValue());
203:
204: Collection col = pg.getAllArticles();
205: int countedSize = col.size(); // force count query
206: Iterator iter = col.iterator();
207: while (iter.hasNext()) {
208: InterfaceArticle a = (InterfaceArticle) iter.next();
209: }
210:
211: assertEquals("compare counted and loaded size", countedSize,
212: col.size());
213:
214: // 7 Articles, 2 Books, 3 Cds
215: assertEquals("check size", col.size(), 12);
216: }
217:
218: public void testReferenceProxies() {
219: ArticleWithReferenceProxy a = new ArticleWithReferenceProxy();
220: // a.setArticleId(8888);
221: a.setArticleName("ProxyExamples.testReferenceProxy article");
222:
223: Query q = QueryFactory.newQuery(a);
224:
225: ProductGroup pg = new ProductGroup();
226: // pg.setId(10);
227: pg.setGroupName("ProxyExamples test group");
228:
229: a.setProductGroup(pg);
230: broker.beginTransaction();
231: broker.store(a);
232: broker.commitTransaction();
233: int id = pg.getGroupId().intValue();
234:
235: broker.clearCache();
236: ArticleWithReferenceProxy ar = (ArticleWithReferenceProxy) broker
237: .getObjectByQuery(q);
238:
239: assertEquals(id, ar.getProductGroup().getId().intValue());
240: }
241:
242: /**
243: * Default the transaction isolation level of a JDBC connection is
244: * READ-COMMITED.
245: * So if a proxy uses another broker instance (i.e. JDBC connecction)
246: * than the current one, it's possible that program blocks.
247: */
248: public void testProxiesAndJDBCTransactionIsolation() {
249: boolean commit = false;
250: try {
251: // Start transaction
252: broker.beginTransaction();
253:
254: // Create productgroup
255: ProductGroupWithCollectionProxy pg = new ProductGroupWithCollectionProxy();
256: pg.setGroupName("TESTPRODUCTGROUP");
257: broker.store(pg);
258:
259: // Create 2 articles for this productgroup
260: for (int j = 1; j <= 2; j++) {
261: Article ar = new Article();
262: ar.setArticleName("ARTICLE " + j);
263: ar.setProductGroup(pg);
264: broker.store(ar);
265: }
266:
267: // Reload the productgroup
268: broker.clearCache();
269: pg = (ProductGroupWithCollectionProxy) broker
270: .getObjectByQuery(QueryFactory.newQuery(pg));
271: assertTrue(pg != null);
272:
273: // Try to load the articles
274: // The proxy is using another broker instance (i.e. JDBC cconnection).
275: // Default the JDBC transaction isolationlevel is READ_COMMITTED.
276: // So the program will wait until the inserted articles are committed.
277: Collection articles = pg.getAllArticlesInGroup();
278: assertEquals(2, articles.size());
279:
280: // Commit
281: broker.commitTransaction();
282: commit = true;
283: } finally {
284: if (!commit)
285: broker.abortTransaction();
286: }
287: }
288:
289: }
|