• Home
  • History
  • Annotate
  • Line#
  • Navigate
  • Raw
  • Download
  • only in /asuswrt-rt-n18u-9.0.0.4.380.2695/release/src-rt/router/db-4.8.30/test/scr024/src/com/sleepycat/persist/test/
1/*-
2 * See the file LICENSE for redistribution information.
3 *
4 * Copyright (c) 2002-2009 Oracle.  All rights reserved.
5 *
6 * $Id$
7 */
8
9package com.sleepycat.persist.test;
10
11import static com.sleepycat.persist.model.Relationship.ONE_TO_MANY;
12import static com.sleepycat.persist.model.Relationship.ONE_TO_ONE;
13import static com.sleepycat.persist.model.DeleteAction.NULLIFY;
14
15import java.math.BigDecimal;
16import java.util.ArrayList;
17import java.util.Collection;
18
19import junit.framework.Test;
20
21import com.sleepycat.db.DatabaseException;
22import com.sleepycat.persist.EntityStore;
23import com.sleepycat.persist.PrimaryIndex;
24import com.sleepycat.persist.StoreConfig;
25import com.sleepycat.persist.model.AnnotationModel;
26import com.sleepycat.persist.model.Entity;
27import com.sleepycat.persist.model.KeyField;
28import com.sleepycat.persist.model.Persistent;
29import com.sleepycat.persist.model.PersistentProxy;
30import com.sleepycat.persist.model.PrimaryKey;
31import com.sleepycat.persist.model.SecondaryKey;
32import com.sleepycat.util.test.TxnTestCase;
33
34/**
35 * Negative tests.
36 *
37 * @author Mark Hayes
38 */
39public class NegativeTest extends TxnTestCase {
40
41    static protected Class<?> testClass = NegativeTest.class;
42
43    public static Test suite() {
44        return txnTestSuite(testClass, null, null);
45    }
46
47    private EntityStore store;
48
49    private void open()
50        throws DatabaseException {
51
52        open(null);
53    }
54
55    private void open(Class<ProxyExtendsEntity> clsToRegister)
56        throws DatabaseException {
57
58        StoreConfig config = new StoreConfig();
59        config.setAllowCreate(envConfig.getAllowCreate());
60        config.setTransactional(envConfig.getTransactional());
61
62        if (clsToRegister != null) {
63            AnnotationModel model = new AnnotationModel();
64            model.registerClass(clsToRegister);
65            config.setModel(model);
66        }
67
68        store = new EntityStore(env, "test", config);
69    }
70
71    private void close()
72        throws DatabaseException {
73
74        store.close();
75        store = null;
76    }
77
78    @Override
79    public void setUp()
80        throws Exception {
81
82        super.setUp();
83    }
84
85    @Override
86    public void tearDown()
87        throws Exception {
88
89        if (store != null) {
90            try {
91                store.close();
92            } catch (Throwable e) {
93                System.out.println("tearDown: " + e);
94            }
95            store = null;
96        }
97        super.tearDown();
98    }
99
100    public void testBadKeyClass1()
101        throws DatabaseException {
102
103        open();
104        try {
105            store.getPrimaryIndex(BadKeyClass1.class, UseBadKeyClass1.class);
106            fail();
107        } catch (IllegalArgumentException expected) {
108            assertTrue(expected.getMessage().indexOf("@KeyField") >= 0);
109        }
110        close();
111    }
112
113    /** Missing @KeyField in composite key class. */
114    @Persistent
115    static class BadKeyClass1 {
116
117        private int f1;
118    }
119
120    @Entity
121    static class UseBadKeyClass1 {
122
123        @PrimaryKey
124        private BadKeyClass1 f1 = new BadKeyClass1();
125
126        @SecondaryKey(relate=ONE_TO_ONE)
127        private BadKeyClass1 f2 = new BadKeyClass1();
128    }
129
130    public void testBadSequenceKeys()
131        throws DatabaseException {
132
133        open();
134        try {
135            store.getPrimaryIndex(Boolean.class, BadSequenceKeyEntity1.class);
136            fail();
137        } catch (IllegalArgumentException expected) {
138            assertTrue(expected.getMessage().indexOf
139                ("Type not allowed for sequence") >= 0);
140        }
141        try {
142            store.getPrimaryIndex(BadSequenceKeyEntity2.Key.class,
143                     BadSequenceKeyEntity2.class);
144            fail();
145        } catch (IllegalArgumentException expected) {
146            assertTrue(expected.getMessage().indexOf
147                ("Type not allowed for sequence") >= 0);
148        }
149        try {
150            store.getPrimaryIndex(BadSequenceKeyEntity3.Key.class,
151                     BadSequenceKeyEntity3.class);
152            fail();
153        } catch (IllegalArgumentException expected) {
154            assertTrue(expected.getMessage().indexOf
155                ("A composite key class used with a sequence may contain " +
156                 "only a single integer key field")>= 0);
157        }
158        close();
159    }
160
161    /** Boolean not allowed for sequence key. */
162    @Entity
163    static class BadSequenceKeyEntity1 {
164
165        @PrimaryKey(sequence="X")
166        private boolean key;
167    }
168
169    /** Composite key with non-integer field not allowed for sequence key. */
170    @Entity
171    static class BadSequenceKeyEntity2 {
172
173        @PrimaryKey(sequence="X")
174        private Key key;
175
176        @Persistent
177        static class Key {
178            @KeyField(1)
179            boolean key;
180        }
181    }
182
183    /** Composite key with multiple key fields not allowed for sequence key. */
184    @Entity
185    static class BadSequenceKeyEntity3 {
186
187        @PrimaryKey(sequence="X")
188        private Key key;
189
190        @Persistent
191        static class Key {
192            @KeyField(1)
193            int key;
194            @KeyField(2)
195            int key2;
196        }
197    }
198
199    /**
200     * A proxied object may not current contain a field that references the
201     * parent proxy.  [#15815]
202     */
203    public void testProxyNestedRef()
204        throws DatabaseException {
205
206        open();
207        PrimaryIndex<Integer,ProxyNestedRef> index = store.getPrimaryIndex
208            (Integer.class, ProxyNestedRef.class);
209        ProxyNestedRef entity = new ProxyNestedRef();
210        entity.list.add(entity.list);
211        try {
212            index.put(entity);
213            fail();
214        } catch (IllegalArgumentException expected) {
215            assertTrue(expected.getMessage().indexOf
216                ("Cannot embed a reference to a proxied object") >= 0);
217        }
218        close();
219    }
220
221    @Entity
222    static class ProxyNestedRef {
223
224        @PrimaryKey
225        private int key;
226
227        ArrayList<Object> list = new ArrayList<Object>();
228    }
229
230    /**
231     * Disallow primary keys on entity subclasses.  [#15757]
232     */
233    public void testEntitySubclassWithPrimaryKey()
234        throws DatabaseException {
235
236        open();
237        PrimaryIndex<Integer,EntitySuperClass> index = store.getPrimaryIndex
238            (Integer.class, EntitySuperClass.class);
239        EntitySuperClass e1 = new EntitySuperClass(1, "one");
240        index.put(e1);
241        assertEquals(e1, index.get(1));
242        EntitySubClass e2 = new EntitySubClass(2, "two", "foo", 9);
243        try {
244            index.put(e2);
245            fail();
246        } catch (IllegalArgumentException e) {
247            assertTrue(e.getMessage().contains
248                ("PrimaryKey may not appear on an Entity subclass"));
249        }
250        assertEquals(e1, index.get(1));
251        close();
252    }
253
254    @Entity
255    static class EntitySuperClass {
256
257        @PrimaryKey
258        private int x;
259
260        private String y;
261
262        EntitySuperClass(int x, String y) {
263            assert y != null;
264            this.x = x;
265            this.y = y;
266        }
267
268        private EntitySuperClass() {}
269
270        @Override
271        public String toString() {
272            return "x=" + x + " y=" + y;
273        }
274
275        @Override
276        public boolean equals(Object other) {
277            if (other instanceof EntitySuperClass) {
278                EntitySuperClass o = (EntitySuperClass) other;
279                return x == o.x && y.equals(o.y);
280            } else {
281                return false;
282            }
283        }
284    }
285
286    @Persistent
287    static class EntitySubClass extends EntitySuperClass {
288
289        @PrimaryKey
290        private String foo;
291
292        private int z;
293
294        EntitySubClass(int x, String y, String foo, int z) {
295            super(x, y);
296            assert foo != null;
297            this.foo = foo;
298            this.z = z;
299        }
300
301        private EntitySubClass() {}
302
303        @Override
304        public String toString() {
305            return super.toString() + " z=" + z;
306        }
307
308        @Override
309        public boolean equals(Object other) {
310            if (other instanceof EntitySubClass) {
311                EntitySubClass o = (EntitySubClass) other;
312                return super.equals(o) && z == o.z;
313            } else {
314                return false;
315            }
316        }
317    }
318
319    /**
320     * Disallow embedded entity classes and subclasses.  [#16077]
321     */
322    public void testEmbeddedEntity()
323        throws DatabaseException {
324
325        open();
326        PrimaryIndex<Integer,EmbeddingEntity> index = store.getPrimaryIndex
327            (Integer.class, EmbeddingEntity.class);
328        EmbeddingEntity e1 = new EmbeddingEntity(1, null);
329        index.put(e1);
330        assertEquals(e1, index.get(1));
331
332        EmbeddingEntity e2 =
333            new EmbeddingEntity(2, new EntitySuperClass(2, "two"));
334        try {
335            index.put(e2);
336            fail();
337        } catch (IllegalArgumentException e) {
338            assertTrue(e.getMessage().contains
339                ("References to entities are not allowed"));
340        }
341
342        EmbeddingEntity e3 = new EmbeddingEntity
343            (3, new EmbeddedEntitySubClass(3, "three", "foo", 9));
344        try {
345            index.put(e3);
346            fail();
347        } catch (IllegalArgumentException e) {
348            assertTrue(e.toString(), e.getMessage().contains
349                ("References to entities are not allowed"));
350        }
351
352        assertEquals(e1, index.get(1));
353        close();
354    }
355
356    @Entity
357    static class EmbeddingEntity {
358
359        @PrimaryKey
360        private int x;
361
362        private EntitySuperClass y;
363
364        EmbeddingEntity(int x, EntitySuperClass y) {
365            this.x = x;
366            this.y = y;
367        }
368
369        private EmbeddingEntity() {}
370
371        @Override
372        public String toString() {
373            return "x=" + x + " y=" + y;
374        }
375
376        @Override
377        public boolean equals(Object other) {
378            if (other instanceof EmbeddingEntity) {
379                EmbeddingEntity o = (EmbeddingEntity) other;
380                return x == o.x &&
381                       ((y == null) ? (o.y == null) : y.equals(o.y));
382            } else {
383                return false;
384            }
385        }
386    }
387
388    @Persistent
389    static class EmbeddedEntitySubClass extends EntitySuperClass {
390
391        private String foo;
392
393        private int z;
394
395        EmbeddedEntitySubClass(int x, String y, String foo, int z) {
396            super(x, y);
397            assert foo != null;
398            this.foo = foo;
399            this.z = z;
400        }
401
402        private EmbeddedEntitySubClass() {}
403
404        @Override
405        public String toString() {
406            return super.toString() + " z=" + z;
407        }
408
409        @Override
410        public boolean equals(Object other) {
411            if (other instanceof EmbeddedEntitySubClass) {
412                EmbeddedEntitySubClass o = (EmbeddedEntitySubClass) other;
413                return super.equals(o) && z == o.z;
414            } else {
415                return false;
416            }
417        }
418    }
419
420    /**
421     * Disallow SecondaryKey collection with no type parameter. [#15950]
422     */
423    public void testTypelessKeyCollection()
424        throws DatabaseException {
425
426        open();
427        try {
428            store.getPrimaryIndex
429                (Integer.class, TypelessKeyCollectionEntity.class);
430            fail();
431        } catch (IllegalArgumentException e) {
432            assertTrue(e.toString(), e.getMessage().contains
433                ("Collection typed secondary key field must have a " +
434                 "single generic type argument and a wildcard or type " +
435                 "bound is not allowed"));
436        }
437        close();
438    }
439
440    @Entity
441    static class TypelessKeyCollectionEntity {
442
443        @PrimaryKey
444        private int x;
445
446        @SecondaryKey(relate=ONE_TO_MANY)
447        private Collection keys = new ArrayList();
448
449        TypelessKeyCollectionEntity(int x) {
450            this.x = x;
451        }
452
453        private TypelessKeyCollectionEntity() {}
454    }
455
456    /**
457     * Disallow a persistent proxy that extends an entity.  [#15950]
458     */
459    public void testProxyEntity()
460        throws DatabaseException {
461
462        try {
463            open(ProxyExtendsEntity.class);
464            fail();
465        } catch (IllegalArgumentException e) {
466            assertTrue(e.toString(), e.getMessage().contains
467                ("A proxy may not be an entity"));
468        }
469    }
470
471    @Persistent(proxyFor=BigDecimal.class)
472    static class ProxyExtendsEntity
473        extends EntitySuperClass
474        implements PersistentProxy<BigDecimal> {
475
476        private String rep;
477
478        public BigDecimal convertProxy() {
479            return new BigDecimal(rep);
480        }
481
482        public void initializeProxy(BigDecimal o) {
483            rep = o.toString();
484        }
485    }
486
487    /**
488     * Wrapper type not allowed for nullified foreign key.
489     */
490    public void testBadNullifyKey()
491        throws DatabaseException {
492
493        open();
494        try {
495            store.getPrimaryIndex(Integer.class, BadNullifyKeyEntity1.class);
496            fail();
497        } catch (IllegalArgumentException expected) {
498            assertTrue(expected.getMessage().indexOf
499                ("NULLIFY may not be used with primitive fields") >= 0);
500        }
501        close();
502    }
503
504    @Entity
505    static class BadNullifyKeyEntity1 {
506
507        @PrimaryKey
508        private int key;
509
510        @SecondaryKey(relate=ONE_TO_ONE,
511                      relatedEntity=BadNullifyKeyEntity2.class,
512                      onRelatedEntityDelete=NULLIFY)
513        private int secKey; // Should be Integer, not int.
514    }
515
516    @Entity
517    static class BadNullifyKeyEntity2 {
518
519        @PrimaryKey
520        private int key;
521    }
522
523    /**
524     * @Persistent not allowed on an enum.
525     */
526    public void testPersistentEnum()
527        throws DatabaseException {
528
529        open();
530        try {
531            store.getPrimaryIndex(Integer.class, PersistentEnumEntity.class);
532            fail();
533        } catch (IllegalArgumentException expected) {
534            assertTrue(expected.getMessage().indexOf
535                ("not allowed for enum, interface, or primitive") >= 0);
536        }
537        close();
538    }
539
540    @Entity
541    static class PersistentEnumEntity {
542
543        @PrimaryKey
544        private int key;
545
546        @Persistent
547        enum MyEnum {X, Y, Z};
548
549        MyEnum f1;
550    }
551
552    /**
553     * Disallow a reference to an interface marked @Persistent.
554     */
555    public void testPersistentInterface()
556        throws DatabaseException {
557
558        open();
559        try {
560            store.getPrimaryIndex(Integer.class,
561                                  PersistentInterfaceEntity1.class);
562            fail();
563        } catch (IllegalArgumentException expected) {
564            assertTrue(expected.getMessage().indexOf
565                ("not allowed for enum, interface, or primitive") >= 0);
566        }
567        close();
568    }
569
570    @Entity
571    static class PersistentInterfaceEntity1 {
572
573        @PrimaryKey
574        private int key;
575
576        @SecondaryKey(relate=ONE_TO_ONE,
577                      relatedEntity=PersistentInterfaceEntity2.class)
578        private int secKey; // Should be Integer, not int.
579    }
580
581    @Persistent
582    interface PersistentInterfaceEntity2 {
583    }
584
585    /**
586     * Disallow reference to @Persistent inner class.
587     */
588    public void testPersistentInnerClass()
589        throws DatabaseException {
590
591        open();
592        try {
593            store.getPrimaryIndex(Integer.class,
594                                  PersistentInnerClassEntity1.class);
595            fail();
596        } catch (IllegalArgumentException expected) {
597            assertTrue(expected.getMessage().indexOf
598                ("Inner classes not allowed") >= 0);
599        }
600        close();
601    }
602
603    @Entity
604    static class PersistentInnerClassEntity1 {
605
606        @PrimaryKey
607        private int key;
608
609        private PersistentInnerClass f;
610    }
611
612    /* An inner (non-static) class is illegal. */
613    @Persistent
614    class PersistentInnerClass {
615
616        private int x;
617    }
618
619    /**
620     * Disallow @Entity inner class.
621     */
622    public void testEntityInnerClass()
623        throws DatabaseException {
624
625        open();
626        try {
627            store.getPrimaryIndex(Integer.class,
628                                  EntityInnerClassEntity.class);
629            fail();
630        } catch (IllegalArgumentException expected) {
631            assertTrue(expected.getMessage().indexOf
632                ("Inner classes not allowed") >= 0);
633        }
634        close();
635    }
636
637    /* An inner (non-static) class is illegal. */
638    @Entity
639    class EntityInnerClassEntity {
640
641        @PrimaryKey
642        private int key;
643    }
644}
645