/*******************************************************************************
* Copyright (c) 2004, 2005 QNX Software Systems and others.
* 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:
* QNX Software Systems - Initial API and implementation
*******************************************************************************/
package org.eclipse.cdt.debug.internal.core.model;
import java.util.ArrayList;
import org.eclipse.cdt.debug.core.CDebugCorePlugin;
import org.eclipse.cdt.debug.core.model.IEnableDisableTarget;
import org.eclipse.cdt.debug.core.model.IPersistableRegisterGroup;
import org.eclipse.cdt.debug.core.model.IRegisterDescriptor;
import org.eclipse.cdt.debug.internal.core.CRegisterManager;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.debug.core.DebugEvent;
import org.eclipse.debug.core.DebugException;
import org.eclipse.debug.core.DebugPlugin;
import org.eclipse.debug.core.model.IRegister;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
/**
* Represents a group of registers.
*/
public class CRegisterGroup extends CDebugElement implements IPersistableRegisterGroup, IEnableDisableTarget {
private static final String ELEMENT_REGISTER_GROUP = "registerGroup"; //$NON-NLS-1$
private static final String ATTR_REGISTER_GROUP_NAME = "name"; //$NON-NLS-1$
private static final String ATTR_REGISTER_GROUP_ENABLED = "enabled"; //$NON-NLS-1$
private static final String ELEMENT_REGISTER = "register"; //$NON-NLS-1$
private static final String ATTR_REGISTER_NAME = "name"; //$NON-NLS-1$
private static final String ATTR_REGISTER_ORIGINAL_GROUP_NAME = "originalGroupName"; //$NON-NLS-1$
private String fName;
private IRegisterDescriptor[] fRegisterDescriptors;
private IRegister[] fRegisters;
private boolean fIsEnabled = true;
private boolean fDisposed = false;
/**
* Constructor for CRegisterGroup.
*/
public CRegisterGroup( CDebugTarget target ) {
super( target );
}
/**
* Constructor for CRegisterGroup.
*/
public CRegisterGroup( CDebugTarget target, String name, IRegisterDescriptor[] descriptors ) {
super( target );
fName = name;
fRegisterDescriptors = descriptors;
}
/* (non-Javadoc)
* @see org.eclipse.debug.core.model.IRegisterGroup#getName()
*/
public String getName() throws DebugException {
return fName;
}
/* (non-Javadoc)
* @see org.eclipse.debug.core.model.IRegisterGroup#getRegisters()
*/
public IRegister[] getRegisters() throws DebugException {
if ( fDisposed )
return new IRegister[0];
if ( fRegisters == null ) {
synchronized( this ) {
if ( fRegisters == null ) {
fRegisters = new IRegister[fRegisterDescriptors.length];
for( int i = 0; i < fRegisters.length; ++i ) {
fRegisters[i] = new CRegister( this, fRegisterDescriptors[i] );
}
}
}
}
return fRegisters;
}
/* (non-Javadoc)
* @see org.eclipse.debug.core.model.IRegisterGroup#hasRegisters()
*/
public boolean hasRegisters() throws DebugException {
return ( fRegisterDescriptors.length > 0 );
}
public void dispose() {
fDisposed = true;
invalidate();
}
public void targetSuspended() {
if ( fRegisters == null ) {
return;
}
for ( int i = 0; i < fRegisters.length; ++i ) {
if ( fRegisters[i] != null && ((CRegister)fRegisters[i]).hasErrors() ) {
((CRegister)fRegisters[i]).resetStatus();
}
}
}
/* (non-Javadoc)
* @see org.eclipse.core.runtime.IAdaptable#getAdapter(java.lang.Class)
*/
public Object getAdapter( Class adapter ) {
if ( IEnableDisableTarget.class.equals( adapter ) )
return this;
return super.getAdapter( adapter );
}
/* (non-Javadoc)
* @see org.eclipse.cdt.debug.core.model.IEnableDisableTarget#canEnableDisable()
*/
public boolean canEnableDisable() {
return true;
}
/* (non-Javadoc)
* @see org.eclipse.cdt.debug.core.model.IEnableDisableTarget#isEnabled()
*/
public boolean isEnabled() {
return fIsEnabled;
}
/* (non-Javadoc)
* @see org.eclipse.cdt.debug.core.model.IEnableDisableTarget#setEnabled(boolean)
*/
public void setEnabled( boolean enabled ) throws DebugException {
if ( fRegisters != null ) {
synchronized( fRegisters ) {
if ( fRegisters != null ) {
for ( int i = 0; i < fRegisters.length; ++i ) {
if ( fRegisters[i] instanceof CRegister ) {
((CRegister)fRegisters[i]).setEnabled( enabled );
}
}
}
}
}
fIsEnabled = enabled;
fireChangeEvent( DebugEvent.CONTENT );
}
public String getMemento() throws CoreException {
Document document = DebugPlugin.newDocument();
Element element = document.createElement( ELEMENT_REGISTER_GROUP );
element.setAttribute( ATTR_REGISTER_GROUP_NAME, getName() );
element.setAttribute( ATTR_REGISTER_GROUP_ENABLED, Boolean.valueOf( isEnabled() ).toString() );
for ( int i = 0; i < fRegisterDescriptors.length; ++i ) {
Element child = document.createElement( ELEMENT_REGISTER );
child.setAttribute( ATTR_REGISTER_NAME, fRegisterDescriptors[i].getName() );
child.setAttribute( ATTR_REGISTER_ORIGINAL_GROUP_NAME, fRegisterDescriptors[i].getGroupName() );
element.appendChild( child );
}
document.appendChild( element );
return DebugPlugin.serializeDocument( document );
}
public void initializeFromMemento( String memento ) throws CoreException {
Node node = DebugPlugin.parseDocument( memento );
if ( node.getNodeType() != Node.ELEMENT_NODE ) {
abort( CoreModelMessages.getString( "CRegisterGroup.0" ), null ); //$NON-NLS-1$
}
Element element = (Element)node;
if ( !ELEMENT_REGISTER_GROUP.equals( element.getNodeName() ) ) {
abort( CoreModelMessages.getString( "CRegisterGroup.1" ), null ); //$NON-NLS-1$
}
String groupName = element.getAttribute( ATTR_REGISTER_GROUP_NAME );
if ( groupName == null || groupName.length() == 0 ) {
abort( CoreModelMessages.getString( "CRegisterGroup.2" ), null ); //$NON-NLS-1$
}
String e = element.getAttribute( ATTR_REGISTER_GROUP_ENABLED );
boolean enabled = Boolean.valueOf( e ).booleanValue();
CRegisterManager rm = getRegisterManager();
ArrayList list = new ArrayList();
Node childNode = element.getFirstChild();
while( childNode != null ) {
if ( childNode.getNodeType() == Node.ELEMENT_NODE ) {
Element child = (Element)childNode;
if ( ELEMENT_REGISTER.equals( child.getNodeName() ) ) {
String name = child.getAttribute( ATTR_REGISTER_NAME );
String originalGroupName = child.getAttribute( ATTR_REGISTER_ORIGINAL_GROUP_NAME );
if ( name == null || name.length() == 0 || originalGroupName == null || originalGroupName.length() == 0 ) {
abort( CoreModelMessages.getString( "CRegisterGroup.3" ), null ); //$NON-NLS-1$
}
else {
IRegisterDescriptor d = rm.findDescriptor( originalGroupName, name );
if ( d != null )
list.add( d );
else
CDebugCorePlugin.log( CoreModelMessages.getString( "CRegisterGroup.4" ) ); //$NON-NLS-1$
}
}
}
childNode = childNode.getNextSibling();
}
setName( groupName );
fRegisterDescriptors = (IRegisterDescriptor[])list.toArray( new IRegisterDescriptor[list.size()] );
setEnabled( enabled );
}
private void abort( String message, Throwable exception ) throws CoreException {
IStatus status = new Status( IStatus.ERROR, CDebugCorePlugin.getUniqueIdentifier(), CDebugCorePlugin.INTERNAL_ERROR, message, exception );
throw new CoreException( status );
}
private void setName( String name ) {
fName = name;
}
/* (non-Javadoc)
* @see org.eclipse.cdt.debug.core.model.IPersistableRegisterGroup#setRegisterDescriptors(org.eclipse.cdt.debug.core.model.IRegisterDescriptor[])
*/
public void setRegisterDescriptors( IRegisterDescriptor[] registerDescriptors ) {
invalidate();
fRegisterDescriptors = registerDescriptors;
}
/* (non-Javadoc)
* @see org.eclipse.cdt.debug.core.model.IPersistableRegisterGroup#getRegisterDescriptors()
*/
public IRegisterDescriptor[] getRegisterDescriptors() {
return fRegisterDescriptors;
}
private CRegisterManager getRegisterManager() {
return (CRegisterManager)getDebugTarget().getAdapter( CRegisterManager.class );
}
private void invalidate() {
if ( fRegisters == null ) {
return;
}
for ( int i = 0; i < fRegisters.length; ++i ) {
if ( fRegisters[i] != null ) {
((CRegister)fRegisters[i]).dispose();
}
}
fRegisters = null;
}
public void resetRegisterValues() {
if ( fRegisters == null ) {
return;
}
for ( int i = 0; i < fRegisters.length; ++i ) {
if ( fRegisters[i] != null ) {
((CRegister)fRegisters[i]).invalidateValue();
}
}
}
}