/******************************************************************************* * Copyright (c) 2009 the CHISEL group and contributors. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * Del Myers - initial API and implementation *******************************************************************************/ package ca.uvic.chisel.javasketch.data.model.imple.internal; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; import java.util.ArrayList; import java.util.Collections; import java.util.List; import ca.uvic.chisel.javasketch.data.SketchDataPlugin; import ca.uvic.chisel.javasketch.data.internal.WriteDataUtils; import ca.uvic.chisel.javasketch.data.model.IActivation; import ca.uvic.chisel.javasketch.data.model.IArrival; import ca.uvic.chisel.javasketch.data.model.ICall; import ca.uvic.chisel.javasketch.data.model.IOriginMessage; import ca.uvic.chisel.javasketch.data.model.IReply; import ca.uvic.chisel.javasketch.data.model.ITargetMessage; import ca.uvic.chisel.javasketch.data.model.IThread; import ca.uvic.chisel.javasketch.data.model.ITraceClass; import ca.uvic.chisel.javasketch.data.model.ITraceClassMethod; import ca.uvic.chisel.javasketch.data.model.ITraceModel; /** * @author Del Myers * */ public class ActivationImpl extends TraceModelIDBase implements IActivation { private ArrivalImpl arrival; private TraceClassImpl traceClass; private TraceClassMethodImpl method; private ArrayList<IOriginMessage> originMessages; private ArrayList<ITargetMessage> targetMessages; private IThread thread; private IOriginMessage replyMessage; private TraceClassImpl thisClass; private boolean dirty; /** * @param trace * @param results * @throws SQLException */ public ActivationImpl(IThread thread, ResultSet results) throws SQLException { super((TraceImpl)thread.getTrace(), results); this.thread = thread; dirty = true; } /* (non-Javadoc) * @see ca.uvic.chisel.javasketch.data.model.imple.internal.TraceModelImpl#load() */ @Override public void load() { try { loadFromResults(getDataUtils().getActivation(getModelID())); } catch (SQLException e) { SketchDataPlugin.getDefault().log(e); } } /* (non-Javadoc) * @see ca.uvic.chisel.javasketch.data.model.IActivation#getCaller() */ public IArrival getArrival() { if (arrival == null) { try { long arrival_id = getLong("arrival_id"); ITraceModel element = ((TraceImpl)getTrace()).findElement("[Message],"+arrival_id); if (element == null) { ResultSet results = ((TraceImpl)getTrace()).getDataUtils().getMessage(arrival_id); arrival = (ArrivalImpl)MessageImpl.createFromResults((ThreadImpl)getThread(), results); } else { arrival = (ArrivalImpl) element; } } catch (SQLException e) { SketchDataPlugin.getDefault().log(e); } } return arrival; } /** * @return */ public IThread getThread() { return thread; } /* (non-Javadoc) * @see ca.uvic.chisel.javasketch.data.model.IActivation#getInstanceID() */ public String getInstanceID() { return getString("instance"); } /* (non-Javadoc) * @see ca.uvic.chisel.javasketch.data.model.IActivation#getMethod() */ public ITraceClassMethod getMethod() { if (method == null) { String methodName = getString("method_name"); String methodSignature = getString("method_signature"); ITraceClass traceClass = getTraceClass(); ITraceModel element = ((TraceImpl)getTrace()).findElement("[METHOD]," + traceClass.getName() +"."+methodName+methodSignature); if (element == null) { method = new TraceClassMethodImpl((TraceClassImpl) traceClass, methodName, methodSignature); } else { method = (TraceClassMethodImpl) element; } } return method; } /* (non-Javadoc) * @see ca.uvic.chisel.javasketch.data.model.IActivation#getOriginMessages() */ public synchronized List<IOriginMessage> getOriginMessages() { if (dirty || originMessages == null) { IOriginMessage lastMessage = null; originMessages = new ArrayList<IOriginMessage>(); try { ResultSet results = getDataUtils().getOriginMessages(getModelID()); while (results.next()) { MessageImpl message = MessageImpl.createFromResults((ThreadImpl)getArrival().getThread(), results); originMessages.add((IOriginMessage)message); lastMessage = (IOriginMessage) message; } if (lastMessage instanceof IReply) { replyMessage = lastMessage; } } catch (SQLException e) { SketchDataPlugin.getDefault().log(e); } dirty = false; } // TODO Auto-generated method stub return Collections.unmodifiableList(originMessages); } /* (non-Javadoc) * @see ca.uvic.chisel.javasketch.data.model.IActivation#getTargetMessages() */ public synchronized List<ITargetMessage> getTargetMessages() { if (targetMessages == null) { targetMessages = new ArrayList<ITargetMessage>(); try { ResultSet results = getDataUtils().getTargetMessages(getModelID()); while (results.next()) { MessageImpl message = MessageImpl.createFromResults((ThreadImpl)getArrival().getThread(), results); targetMessages.add((ITargetMessage)message); } } catch (SQLException e) { SketchDataPlugin.getDefault().log(e); } } return Collections.unmodifiableList(targetMessages); } /* (non-Javadoc) * @see ca.uvic.chisel.javasketch.data.model.IActivation#getTraceClass() */ public ITraceClass getTraceClass() { if (traceClass == null) { String className = getString("type_name"); ITraceModel element = ((TraceImpl)getTrace()).findElement("[TraceClass]," + className); if (element == null) { //create a new one traceClass = new TraceClassImpl((TraceImpl)getTrace(), className); } else { traceClass = (TraceClassImpl) element; } } return traceClass; } /* (non-Javadoc) * @see ca.uvic.chisel.javasketch.data.model.IActivation#getDuration() */ public long getDuration() { return getLastMessageTime() - getArrival().getTime(); } /* (non-Javadoc) * @see ca.uvic.chisel.javasketch.data.model.IActivation#getTime() */ public long getTime() { return getArrival().getTime(); } /** * Gets the last message sent from this activation, which should be either * a reply or a throw. * @return */ private long getLastMessageTime() { getOriginMessages(); if (replyMessage != null) { return replyMessage.getTime(); } if (replyMessage == null) { try { Statement s = ((TraceImpl)getTrace()).getConnection().createStatement(); ResultSet results = s.executeQuery("SELECT MAX(order_num) FROM Message WHERE activation_id=" + getModelID() + " AND (kind='REPLY' OR kind='THROW')"); if (results.next()) { return results.getLong(1); } } catch (SQLException e) { SketchDataPlugin.getDefault().log(e); } } return 0; } /* (non-Javadoc) * @see ca.uvic.chisel.javasketch.data.model.IActivation#getThisClass() */ public ITraceClass getThisClass() { if (thisClass == null) { String className = getString("this_type"); ITraceModel element = ((TraceImpl)getTrace()).findElement("[TraceClass]," + className); if (element == null) { //create a new one thisClass = new TraceClassImpl((TraceImpl)getTrace(), className); } else { thisClass = (TraceClassImpl) element; } } return thisClass; } /* (non-Javadoc) * @see java.lang.Object#toString() */ @Override public String toString() { String sequence = ""; if (getArrival() != null) { ITargetMessage arrival = getArrival(); if (arrival.getOrigin() instanceof ICall) { ICall call = (ICall) arrival.getOrigin(); sequence = WriteDataUtils.fromStoredSequenceString(call.getSequence()); } } String method = getMethod().getName() + getMethod().getSignature(); return sequence + " " + method; } /** * @param b */ public void setDirty(boolean b) { dirty = b; } /* (non-Javadoc) * @see ca.uvic.chisel.javasketch.data.model.ITraceModel#getKind() */ public int getKind() { return ACTIVATION; } public static final String getIdentifierFromModel(String modelID) { return "[ACTIVATION]," + modelID; } }