|
What this is
Other links
The source code/* * Sun Public License Notice * * The contents of this file are subject to the Sun Public License * Version 1.0 (the "License"). You may not use this file except in * compliance with the License. A copy of the License is available at * http://www.sun.com/ * * The Original Code is NetBeans. The Initial Developer of the Original * Code is Sun Microsystems, Inc. Portions Copyright 1997-2001 Sun * Microsystems, Inc. All Rights Reserved. */ package org.netbeans.mdr.test; import java.io.*; import java.util.*; import org.netbeans.api.mdr.*; import org.openide.util.Lookup; import org.netbeans.lib.jmi.xmi.*; import org.netbeans.lib.jmi.util.*; import javax.jmi.reflect.*; import javax.jmi.model.*; /** * Generates random data (instances, attribute values, links) in a given package. */ public class RandomDataSupport extends Object { // variables ................................................................ // used random generator private Random random = new Random (); // extent in which random data are generated private RefPackage target; private HashSet trackedPackages = new HashSet(); // maximal number of instances that should be generated per one class proxy private int maxInstancesPerClass; private RefClass[] allClasses; private RefAssociation[] allAssociations; private ArrayList toDelete; // stores the number of created instaces private int instancesCounter = 0; // stores the number of created links private int linksCounter = 0; private int othersCounter = 0; private ElementsCache elementsCache; private boolean warmUp; private boolean testRun; // init ..................................................................... public RandomDataSupport(RefPackage pkg) { target = pkg; elementsCache = new ElementsCache (target); prepareAllClasses(); prepareAllAssociations(); } // methods .................................................................. /** * Generates random objects in given extent. * * @param target extent * @param randSeed value to initialize random generator with * @param max maximal number of instances that should be generated per one class proxy */ public void generateObjects (long randSeed, int max, boolean warmUp, boolean testRun) { random.setSeed (randSeed); instancesCounter = 0; this.maxInstancesPerClass = max; this.warmUp = warmUp; this.testRun = testRun; for (int i = 0; i < allClasses.length; i++) { RefClass proxy = allClasses[i]; MofClass metaClass = (MofClass) proxy.refMetaObject (); if (!metaClass.isAbstract ()) { int count = (warmUp ? 1 : 1 + random.nextInt (maxInstancesPerClass)); for (int x = 0; x < count; x++) generateInstance (metaClass); } } } public void modifyObjects (long randSeed, int max, boolean warmUp, boolean testRun) { random.setSeed (randSeed); instancesCounter = 0; this.maxInstancesPerClass = max; this.warmUp = warmUp; this.testRun = testRun; for (int i = 0; i < allClasses.length; i++) { RefClass proxy = allClasses[i]; MofClass metaClass = (MofClass) proxy.refMetaObject (); if (!metaClass.isAbstract ()) { int count = (warmUp ? 1 : 1 + random.nextInt (maxInstancesPerClass)); for (int x = 0; x < count; x++) modifyInstance (metaClass); } } } public void prepareAssociationEnds() { for (int i = 0; i < allAssociations.length; i++) elementsCache.associationEndInstances ((Association)allAssociations[i].refMetaObject()); } /** * Generates random assiciations in given extent. * * @param target extent * @param randSeed value to initialize random generator with * @param max maximal number of instances that should be generated per one class proxy */ public void generateAssociations (long randSeed, int max, boolean warmUp, boolean testRun) { random.setSeed (randSeed); instancesCounter = 0; linksCounter = 0; this.maxInstancesPerClass = max; this.warmUp = warmUp; this.testRun = testRun; for (int i = 0; i < allAssociations.length; i++) { RefAssociation assoc = allAssociations[i]; Association metaAssoc = (Association) assoc.refMetaObject (); if (!metaAssoc.isAbstract () && !metaAssoc.isDerived ()) { int count = (warmUp ? 1 : 1 + random.nextInt (maxInstancesPerClass)); for (int x = 0; x < count; x++) generateAssociation (metaAssoc); } } } public void findAllOfClass(int idx) { allClasses[idx].refAllOfClass(); } public int iterateAllOfClass(int idx) { int i = 0; for (Iterator it = allClasses[idx].refAllOfClass().iterator(); it.hasNext(); it.next()) i++; return i; } public int queryAssociations(long randSeed, int max) { random.setSeed(randSeed); othersCounter = 0; int totalNumOfIter = 0; for (int i = 0; i < allAssociations.length; i++) { RefAssociation assoc = allAssociations[i]; if (((Association)assoc.refMetaObject()).isDerived()) continue; int numOfIter = random.nextInt(max); for (int j = 0; j < numOfIter; j++) { int end = random.nextInt(2); RefObject[] inst = (RefObject[])elementsCache.associationEndInstances((Association)assoc.refMetaObject()).get(end); if (inst.length == 0) continue; AssociationEnd aEnd = (AssociationEnd)elementsCache.associationEnds((Association)assoc.refMetaObject()).get(end); if (!aEnd.otherEnd().isNavigable()) continue; Collection others = assoc.refQuery(aEnd, inst[random.nextInt(inst.length)]); totalNumOfIter++; for (Iterator it = others.iterator(); it.hasNext(); it.next()) othersCounter++; } } return totalNumOfIter; } public int prepareObjectsToDelete(long randSeed, int max) { random.setSeed(randSeed); toDelete = new ArrayList(); HashSet composites = new HashSet(); for (int i = 0; i < allClasses.length; i++) { Collection col = allClasses[i].refAllOfClass(); for (Iterator it = col.iterator(); it.hasNext();) { RefObject next = (RefObject)it.next(); RefFeatured composite = next.refOutermostComposite(); if ((random.nextInt(col.size()) < max) && (!composites.contains(composite))) { toDelete.add(next); composites.add(composite); } } } return toDelete.size(); } public void deleteObjects() { for (int i = 0; i < toDelete.size(); i++) { RefObject obj = (RefObject)toDelete.get(i); obj.refDelete(); } } public int getInstancesCounter() { return instancesCounter; } public int getLinksCounter() { return linksCounter; } public int getOthersCounter() { return othersCounter; } public int getNumberOfClasses() { return allClasses.length; } // private methods ......................................................... private RefStruct generateStructure (StructureType type) { List fields = elementsCache.structureFields (type); List values = new LinkedList (); Iterator iter = fields.iterator (); while (iter.hasNext ()) { StructureField field = (StructureField) iter.next (); Classifier fieldType = field.getType (); values.add (generateValue (fieldType)); } RefBaseObject proxy = elementsCache.findProxy (type); if (testRun) return null; if (proxy instanceof RefClass) return ((RefClass) proxy).refCreateStruct (type, values); else return ((RefPackage) proxy).refCreateStruct (type, values); } private RefEnum generateEnumeration (EnumerationType type) { List labels = type.getLabels (); int index = random.nextInt (labels.size ()); RefBaseObject proxy = elementsCache.findProxy (type); if (testRun) return null; if (proxy instanceof RefClass) return ((RefClass) proxy).refGetEnum (type, (String) labels.get (index)); else return ((RefPackage) proxy).refGetEnum (type, (String) labels.get (index)); } private Object generatePrimitive (PrimitiveType type) { String typeName = type.getName (); if (XmiConstants.BOOLEAN_TYPE.equals (typeName)) return random.nextBoolean () ? Boolean.TRUE : Boolean.FALSE; if (XmiConstants.DOUBLE_TYPE.equals (typeName)) return new Double (random.nextDouble ()); if (XmiConstants.FLOAT_TYPE.equals (typeName)) return new Float (random.nextFloat ()); if (XmiConstants.INTEGER_TYPE.equals (typeName)) return new Integer (random.nextInt ()); if (XmiConstants.LONG_TYPE.equals (typeName)) return new Long (random.nextLong ()); if (XmiConstants.STRING_TYPE.equals (typeName)) return generateString (); throw new DebugException ("Unknown type: " + typeName); } private String generateString () { int length = random.nextInt (20); byte [] chars = new byte [length]; random.nextBytes (chars); for (int x = 0; x < length; x++) chars [x] = (byte) ('a' + Math.abs (chars [x] % 24)); // convert to alpha characters only return new String (chars); } private Object generateValue (Classifier type) { while (type instanceof AliasType) type = ((AliasType) type).getType (); if (type instanceof MofClass) return generateInstance ((MofClass) type); if (type instanceof PrimitiveType) return generatePrimitive ((PrimitiveType) type); if (type instanceof StructureType) return generateStructure ((StructureType) type); if (type instanceof EnumerationType) return generateEnumeration ((EnumerationType) type); throw new DebugException ("Unknown or unsupported type: " + type.getName ()); } private RefObject generateInstance (MofClass mofClass) { RefPackage refPackage = (RefPackage) elementsCache.findProxy (mofClass); RefClass proxy = refPackage.refClass (mofClass); List args = new LinkedList (); Iterator iter = elementsCache.instanceAttributes (mofClass).iterator (); while (iter.hasNext ()) { Attribute attr = (Attribute) iter.next (); args.add (generateAttributeValue (attr)); } // while instancesCounter++; if (testRun) return null; return proxy.refCreateInstance (args); } private RefObject modifyInstance(MofClass mofClass) { RefObject inst = findInstance(elementsCache.classInstances(mofClass)); List list = elementsCache.instanceAttributes (mofClass); if (list.size() > 0) { int idx = random.nextInt(list.size()); Attribute attr = (Attribute) list.get (idx); if (attr.isChangeable()) { Object value = generateAttributeValue (attr); if (!testRun) inst.refSetValue(attr, value); instancesCounter++; } } return inst; } private RefObject findInstance (RefObject[] objs) { if (objs == null || objs.length == 0) return null; return objs[random.nextInt(objs.length)]; } private Object generateAttributeValue (Attribute attribute) { MultiplicityType multType = attribute.getMultiplicity (); Classifier type = attribute.getType (); while (type instanceof AliasType) type = ((AliasType) type).getType (); // check, if type is not an abstract class, if so find a suitable descendant if ((type instanceof MofClass) && ((MofClass) type).isAbstract ()) type = findSubtype ((MofClass) type); int upper = multType.getUpper (); int lower = multType.getLower (); boolean isMultivalued = upper != 1; if ((lower == 0) && random.nextBoolean ()) { // if the attribute is optional, generate no value with 50% probality return isMultivalued ? new LinkedList () : null; } if (!isMultivalued) return generateValue (type); // [PENDING] it would be better to generate instances of // various subtypes of a given type ... if (upper == -1) upper = lower + 3; int count = lower + random.nextInt (upper - lower + 2); // we limit the nuber of generated values to be between 1 and 10 if (count == 0) count = 1; if (count > 10) count = 10; List values = new LinkedList (); for (int x = 0; x < count; x++) values.add (generateValue (type)); return values; } private MofClass findSubtype (MofClass mofClass) { List list = elementsCache.nonAbstractSubtypes (mofClass); if ((list == null) || (list.size () == 0)) throw new DebugException ("Cannot find a non-abstract subtype: " + mofClass.getName ()); int index = random.nextInt (list.size ()); return (MofClass) list.get (index); } private void generateAssociation (Association mofAssoc) { RefPackage refPackage = (RefPackage) elementsCache.findProxy (mofAssoc); RefAssociation proxy = refPackage.refAssociation (mofAssoc); List ends = elementsCache.associationEnds (mofAssoc); List endInstances = elementsCache.associationEndInstances (mofAssoc); AssociationEnd aEnd = (AssociationEnd) ends.get (0); RefObject obj1 = null; if (aEnd.otherEnd().getAggregation() == AggregationKindEnum.COMPOSITE) { Classifier type = aEnd.getType (); while (type instanceof AliasType) type = ((AliasType) type).getType (); // check, if type is not an abstract class, if so find a suitable descendant if ((type instanceof MofClass) && ((MofClass) type).isAbstract ()) type = findSubtype ((MofClass) type); obj1 = generateInstance((MofClass)type); } else { obj1 = findInstance((RefObject[])endInstances.get(0)); if (obj1 == null) return; int bound = aEnd.getMultiplicity().getUpper(); if (bound != -1 && proxy.refQuery(aEnd, obj1).size() >= bound) return; } aEnd = (AssociationEnd) ends.get (1); RefObject obj2 = null; if (aEnd.otherEnd().getAggregation() == AggregationKindEnum.COMPOSITE) { Classifier type = aEnd.getType (); while (type instanceof AliasType) type = ((AliasType) type).getType (); // check, if type is not an abstract class, if so find a suitable descendant if ((type instanceof MofClass) && ((MofClass) type).isAbstract ()) type = findSubtype ((MofClass) type); obj2 = generateInstance((MofClass)type); } else { obj2 = findInstance((RefObject[])endInstances.get(1)); if (obj2 == null) return; int bound = aEnd.getMultiplicity().getUpper(); if (bound != -1 && proxy.refQuery(aEnd, obj2).size() >= bound) return; } if (testRun) return; proxy.refAddLink (obj1, obj2); linksCounter++; } private void prepareAllClasses () { trackedPackages.clear(); Collection col = findAllClasses (target); allClasses = (RefClass[]) col.toArray(new RefClass[col.size()]); } private Collection findAllClasses (RefPackage target) { if (trackedPackages.contains (target)) return null; trackedPackages.add (target); Collection clss = target.refAllClasses (); Iterator iter = target.refAllPackages ().iterator (); while (iter.hasNext ()) clss.addAll(findAllClasses ((RefPackage) iter.next ())); return clss; } private void prepareAllAssociations () { trackedPackages.clear(); Collection col = findAllAssociations (target); allAssociations = (RefAssociation[]) col.toArray(new RefAssociation[col.size()]); } private Collection findAllAssociations (RefPackage target) { if (trackedPackages.contains (target)) return null; trackedPackages.add (target); Collection assocs = target.refAllAssociations (); Iterator iter = target.refAllPackages ().iterator (); while (iter.hasNext ()) assocs.addAll(findAllAssociations ((RefPackage) iter.next ())); return assocs; } } |
... this post is sponsored by my books ... | |
#1 New Release! |
FP Best Seller |
Copyright 1998-2021 Alvin Alexander, alvinalexander.com
All Rights Reserved.
A percentage of advertising revenue from
pages under the /java/jwarehouse
URI on this website is
paid back to open source projects.