//
// This file is part of the prose package.
//
// The contents of this file are subject to the Mozilla Public License
// Version 1.1 (the "License"); you may not use this file except in
// compliance with the License. You may obtain a copy of the License at
// http://www.mozilla.org/MPL/
//
// Software distributed under the License is distributed on an "AS IS" basis,
// WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
// for the specific language governing rights and limitations under the
// License.
//
// The Original Code is prose.
//
// The Initial Developer of the Original Code is Andrei Popovici. Portions
// created by Andrei Popovici are Copyright (C) 2002 Andrei Popovici.
// All Rights Reserved.
//
// Contributor(s):
// $Id: QueryManager.java,v 1.3 2008/11/18 11:42:36 anicoara Exp $
// =====================================================================
//
package ch.ethz.prose.query;
// used packages
import ch.ethz.prose.AspectManager;
import ch.ethz.prose.Aspect;
import ch.ethz.prose.crosscut.Crosscut;
import java.util.List;
import java.util.Vector;
import java.util.Iterator;
import java.util.Comparator;
import java.util.Collections;
import java.util.Set;
import java.util.HashSet;
import ch.ethz.prose.engine.JoinPointRequest;
import ch.ethz.prose.engine.JoinPointManager;
/**
* Class QueryManager
*
* @version $Revision: 1.3 $
* @author Andrei Popovici
*/
public class QueryManager {
public static final int SELECT_ASPECT = 0x01; // must be the minimum value of the 'SELECT' constants
public static final int SELECT_CROSSCUT = 0x02;
public static final int SELECT_JOINPOINT = 0x04;
public static final int GROUP_BY_ASPECT = 0x01;
public static final int GROUP_BY_CROSSCUT = 0x02;
public static final int GROUP_BY_JOINPOINT = 0x04;
public static final int SELECT_ALL = SELECT_ASPECT | SELECT_CROSSCUT | SELECT_JOINPOINT;
AspectManager aspectMgr = null;
JoinPointManager jpMgr = null;
public QueryManager(AspectManager am) {
if (am == null)
throw new IllegalArgumentException("QueryManager.init: null am");
aspectMgr = am;
jpMgr = am.getJoinPointManager();
}
/**
* This method processes the system (of its <code>AspectManager</code>) for finding a duplicate free
* result <code>List</code> consisting of three columns:
* <ul>
* <li><code>Aspect</code>
* <li><code>Crosscut</code>
* <li><code>JoinPointRequest</code>
* </ul>
* As input it takes a <code>List</code> of <code>Aspect</code> and two <code>int</code>'s indicating
* which columns are selected and by which column the result is grouped.
*
* Through the logical <code>OR</code> combination of the three member constants <code>SELECT_ASPECT</code>,
* <code>SELECT_CROSSCUT</code> and <code>SELECT_JOINPOINT</code> every possible opportunity of selecting the columns is
* reached.
*
* The value of the <code>groupBy</code> variable should be in accordance with one of the codes <code>GROUP_BY_ASPECT</code>,
* <code>GROUP_BY_CROSSCUT</code> or <code>GROUP_BY_JOINPOINT</code>. If the value differs from one of these member constants, the
* default constant <code>GROUP_BY_ASPECT</code> is assigned.
*
* @param aspectList The list that is processed for searching all corresponding crosscuts and their joinpoints.
* @param selectFields The constant that indicates which columns are selected in the result. The non-selected
* columns are set to <code>null</code>. An input value other than explained above raises an Exception.
* @param groupBy Indicates if the result table is grouped by aspects, crosscuts or joinpoints. By default
* they are grouped by aspects.
*/
public List queryAspects(List aspectList, int selectFields, int groupBy) {
if (selectFields == 0)
return new Vector();
HashSet result = new HashSet();
Iterator i = aspectList.iterator();
while (i.hasNext()) {
AspectSurrogate as = (AspectSurrogate)i.next();
Aspect crtAspect = reconstructAspect(as);
if (crtAspect != null) {
Iterator j = crtAspect.getCrosscuts().iterator();
if (!j.hasNext()) result.add(createTuple(as,null,null,selectFields));
while (j.hasNext()) {
Crosscut crtCrosscut = (Crosscut)j.next();
Iterator k = jpMgr.getJoinpoints(crtCrosscut).iterator();
CrosscutSurrogate cs = new CrosscutSurrogate(as,crtCrosscut);
if (!k.hasNext()) result.add(createTuple(as,cs,null,selectFields));
while (k.hasNext()) {
JoinPointRequest crtJpr = (JoinPointRequest)k.next();
result.add(createTuple(as,cs,crtJpr,selectFields));
}
}
}
}
return sortTupleList(new Vector(result),groupBy);
}
public List queryCrosscuts(List crosscutList, int selectFields, int groupBy) {
if (selectFields == 0)
return new Vector();
HashSet result = new HashSet();
Iterator i = crosscutList.iterator();
while (i.hasNext()) {
try {
CrosscutSurrogate cs = (CrosscutSurrogate)i.next();
AspectSurrogate as = cs.getOwnerSurrogate();
Crosscut crtCrosscut = reconstructCrosscut(cs);
Iterator k = jpMgr.getJoinpoints(crtCrosscut).iterator();
if (!k.hasNext()) result.add(createTuple(as,cs,null,selectFields));
while (k.hasNext()) {
JoinPointRequest crtJpr = (JoinPointRequest)k.next();
result.add(createTuple(as,cs,crtJpr,selectFields));
}
}
catch (ClassNotFoundException e) {
// The following exception are CAUGHT and not propagated. The
// reason is that a surrogate may come from a remote machine
// and may attempt to instantiate a method or a class (etc)
// which does not exist on our VM. This being the case,
// we skip this iteration
}
}
return sortTupleList(new Vector(result),groupBy);
}
public List queryJoinpoints(List jpList, int selectFields, int groupBy) {
if (selectFields == 0)
return new Vector();
HashSet result = new HashSet();
Iterator i = new HashSet(jpList).iterator();
while (i.hasNext()) {
try {
JoinPointRequestSurrogate jprs = (JoinPointRequestSurrogate)i.next();
JoinPointRequest jpr = reconstructRequest(jprs);
Iterator j = jpMgr.getCrosscuts(jpr).iterator();
while (j.hasNext()) {
Crosscut crtCrosscut = (Crosscut)j.next();
Aspect crtAspect = crtCrosscut.getOwner();
result.add(createTuple(crtAspect,crtCrosscut,jprs,selectFields));
}
}
// The following exception are CAUGHT and not propagated. The
// reason is that a surrogate may come from a remote machine
// and may attempt to instantiate a method or a class (etc)
// which does not exist on our VM. This being the case,
// we skip this iteration
catch (ClassNotFoundException e) {}
catch (NoSuchMethodException e) {}
catch (NoSuchFieldException e) {}
}
return sortTupleList(new Vector(result),groupBy);
}
public List queryAllJoinpoints() {
Set jpSur = new HashSet();
Iterator i = jpMgr.allJoinpoints().iterator();
while (i.hasNext())
jpSur.add(new JoinPointRequestSurrogate((JoinPointRequest)i.next()));
List jpSurList = new Vector(jpSur);
return jpSurList;
}
public List queryAllAspects() {
Set apSur = new HashSet();
Iterator i = aspectMgr.getAllAspects().iterator();
while (i.hasNext())
apSur.add(new AspectSurrogate((Aspect)i.next()));
return new Vector(apSur);
}
private List sortTupleList(List lst, int groupBy) {
if (groupBy != 0)
Collections.sort(lst,new TupleComparator(groupBy));
return lst;
}
static class TupleComparator implements Comparator {
int groupBy;
TupleComparator(int groupBy) {
this.groupBy=groupBy;
}
private int doHashCode(Object o) {
if (o == null)
return 0;
else
return o.hashCode();
}
private int doEquals(Object o1, Object o2) {
int compareVal = doHashCode(o1) - doHashCode(o2);
if (compareVal != 0)
return compareVal;
if (o1 != null && o1.equals(o2))
return 0;
else
return 1;
}
public int compare(Object o1, Object o2) {
int hvalCompare;
Tuple t1 = (Tuple)o1;
Tuple t2 = (Tuple)o2;
switch (groupBy) {
case GROUP_BY_ASPECT:
hvalCompare = doEquals(t1.getAspectSurrogate(),t2.getAspectSurrogate());
break;
case GROUP_BY_JOINPOINT:
hvalCompare = doEquals(t1.getRequestSurrogate(),t2.getRequestSurrogate());
break;
case GROUP_BY_CROSSCUT:
hvalCompare = doEquals(t1.getAspectSurrogate(),t2.getAspectSurrogate());
if (hvalCompare == 0)
hvalCompare = doEquals(t1.getCrosscutSurrogate(),t2.getCrosscutSurrogate());
break;
default:
throw new IllegalArgumentException("Illegal groupByValue");
}
// System.err.println("\nt1: " + t1 + "\n" + t2 + " ->RESULT: " + hvalCompare);
return hvalCompare;
}
}
protected Tuple createTuple(AspectSurrogate as, CrosscutSurrogate cs, JoinPointRequest jpr, int selectFields) {
Tuple result = new Tuple();
if ( (selectFields & SELECT_ASPECT) != 0 )
result.setAspectSurrogate(as);
if ( (selectFields & SELECT_CROSSCUT) != 0 )
result.setCrosscutSurrogate(cs);
if ( (selectFields & SELECT_JOINPOINT) != 0) {
if (jpr == null)
result.setRequestSurrogate(null);
else
result.setRequestSurrogate(new JoinPointRequestSurrogate(jpr));
}
return result;
}
protected Tuple createTuple(Aspect a, Crosscut c, JoinPointRequestSurrogate jprs, int selectFields) {
Tuple result = new Tuple();
AspectSurrogate as = null;
if ( (selectFields & SELECT_ASPECT) != 0 ) {
if (a!= null)
as = new AspectSurrogate(a);
else
as = null;
result.setAspectSurrogate(as);
}
if ( (selectFields & SELECT_CROSSCUT) != 0 ) {
if (as == null) {
if (a != null)
as = new AspectSurrogate(a);
else
as = null;
}
result.setCrosscutSurrogate( new CrosscutSurrogate(as,c));
}
if ( (selectFields & SELECT_JOINPOINT) != 0)
result.setRequestSurrogate(jprs);
return result;
}
public Aspect reconstructAspect(AspectSurrogate as) {
List lst = aspectMgr.getAllAspects();
Iterator i = lst.iterator();
while (i.hasNext()) {
Aspect crtAsp = (Aspect)(i.next());
if (crtAsp.getAssociatedObject().equals(as.getAssociatedObject()) &&
crtAsp.getClass().getName().equals(as.getAspectClassName()))
return crtAsp;
}
return null;
}
protected Crosscut reconstructCrosscut(CrosscutSurrogate cs) throws ClassNotFoundException {
Aspect a = reconstructAspect(cs.getOwnerSurrogate());
if (a == null)
return null;
return (Crosscut)a.getCrosscuts().get(cs.getIndex());
}
/**
* Returns a <code>JoinPointRequest</code> Object that is represented by this
* <code>JoinPointRequestSurrogate</code>.
*
* @exception ClassNotFoundException can be thrown if the class of a required name or type or is not available.
* @exception NoSuchMethodException can be thrown while the creation of a <code>MethodEntryRequest</code> or a
* <code>MethodExitRequest</code>.
* @exception NoSuchFieldException can be thrown while the creation of a <code>FieldAccessRequest</code> or a
* <code>FieldModificationRequest</code>.
*/
protected JoinPointRequest reconstructRequest(JoinPointRequestSurrogate jprs)
throws ClassNotFoundException, NoSuchMethodException, NoSuchFieldException {
return jpMgr.createJoinPointRequest(jprs.getKind(),jprs.getMember().toRealInstance());
}
}