/******************************************************************************
* Copyright (c) 2016 Oracle
* 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:
* Konstantin Komissarchik - initial implementation and ongoing maintenance
******************************************************************************/
package org.eclipse.sapphire.modeling.xml;
import org.eclipse.sapphire.Element;
import org.eclipse.sapphire.FilteredListener;
import org.eclipse.sapphire.Listener;
import org.eclipse.sapphire.Property;
import org.eclipse.sapphire.PropertyContentEvent;
import org.w3c.dom.Node;
/**
* @author <a href="mailto:konstantin.komissarchik@oracle.com">Konstantin Komissarchik</a>
*/
public class VirtualChildXmlResource extends XmlResource
{
private final XmlPath path;
private Node lastDomNode;
public VirtualChildXmlResource( final XmlResource parent,
final XmlPath path )
{
super( parent );
this.path = path;
}
@Override
public XmlResource parent()
{
return (XmlResource) super.parent();
}
@Override
public void init( final Element element )
{
super.init( element );
final Listener listener = new FilteredListener<PropertyContentEvent>()
{
@Override
protected void handleTypedEvent( final PropertyContentEvent event )
{
removeIfEmpty();
}
};
for( Property property : element.properties() )
{
property.attach( listener );
}
}
@Override
public XmlElement getXmlElement( final boolean createIfNecessary )
{
final XmlElement parent = parent().getXmlElement( createIfNecessary );
XmlElement element = null;
if( parent != null )
{
element = (XmlElement) parent.getChildNode( this.path, createIfNecessary );
}
Node node = null;
if( element != null )
{
node = element.getDomNode();
}
if( this.lastDomNode != node )
{
final XmlResourceStore store = adapt( RootXmlResource.class ).store();
final Element modelElement = element();
if( this.lastDomNode != null )
{
store.unregisterModelElement( this.lastDomNode, modelElement );
}
if( node != null )
{
store.registerModelElement( node, modelElement );
}
this.lastDomNode = node;
}
return element;
}
private void removeIfEmpty()
{
final XmlElement base = parent().getXmlElement( false );
if( base != null )
{
final XmlElement element = (XmlElement) base.getChildNode( this.path, false );
if( element != null && element != base && element.isEmpty() )
{
base.removeChildNode( this.path );
}
}
}
}