/* ******************************************************************************
* Copyright (c) 2006-2012 XMind Ltd. and others.
*
* This file is a part of XMind 3. XMind releases 3 and
* above are dual-licensed under the Eclipse Public License (EPL),
* which is available at http://www.eclipse.org/legal/epl-v10.html
* and the GNU Lesser General Public License (LGPL),
* which is available at http://www.gnu.org/licenses/lgpl.html
* See http://www.xmind.net/license.html for details.
*
* Contributors:
* XMind Ltd. - initial API and implementation
*******************************************************************************/
package org.xmind.core.internal.dom;
import static org.xmind.core.internal.dom.DOMConstants.ATTR_ID;
import static org.xmind.core.internal.dom.DOMConstants.ATTR_STYLE_ID;
import static org.xmind.core.internal.dom.DOMConstants.ATTR_THEME;
import static org.xmind.core.internal.dom.DOMConstants.TAG_RELATIONSHIP;
import static org.xmind.core.internal.dom.DOMConstants.TAG_RELATIONSHIPS;
import static org.xmind.core.internal.dom.DOMConstants.TAG_TITLE;
import static org.xmind.core.internal.dom.DOMConstants.TAG_TOPIC;
import java.util.Collections;
import java.util.Set;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.xmind.core.Core;
import org.xmind.core.ILegend;
import org.xmind.core.IRelationship;
import org.xmind.core.ISheetSetting;
import org.xmind.core.ISheetSettings;
import org.xmind.core.ITopic;
import org.xmind.core.IWorkbook;
import org.xmind.core.event.ICoreEventListener;
import org.xmind.core.event.ICoreEventRegistration;
import org.xmind.core.event.ICoreEventSource;
import org.xmind.core.event.ICoreEventSupport;
import org.xmind.core.internal.Sheet;
import org.xmind.core.util.DOMUtils;
import org.xmind.core.util.ILabelRefCounter;
import org.xmind.core.util.IMarkerRefCounter;
/**
* @author Brian Sun
* @author Frank Shaka
*/
public class SheetImpl extends Sheet implements ICoreEventSource {
private static final Set<IRelationship> NO_RELATIONSHIPS = Collections
.emptySet();
private Element implementation;
private WorkbookImpl ownedWorkbook;
private SheetMarkerRefCounter markerRefCounter = null;
private SheetLabelRefCounter labelRefCounter = null;
private LegendImpl legend = null;
private ISheetSetting setting;
private ISheetSettings settings;
/**
* @param implementation
*/
public SheetImpl(Element implementation, WorkbookImpl ownedWorkbook) {
super();
this.ownedWorkbook = ownedWorkbook;
this.implementation = DOMUtils.addIdAttribute(implementation);
DOMUtils.ensureChildElement(implementation, TAG_TOPIC);
//((TopicImpl) getRootTopic()).addNotify(ownedWorkbook, this, null);
}
/**
* @return the implementation
*/
public Element getImplementation() {
return implementation;
}
public int hashCode() {
return implementation.hashCode();
}
/**
* @see java.lang.Object#equals(java.lang.Object)
*/
@Override
public boolean equals(Object obj) {
if (obj == this)
return true;
if (obj == null || !(obj instanceof SheetImpl))
return false;
SheetImpl t = (SheetImpl) obj;
return implementation == t.implementation;
}
public String toString() {
return "SHT#" + getId() + "(" + getTitleText() + ")"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
}
public <T> T getAdapter(Class<T> adapter) {
if (ICoreEventSource.class.equals(adapter))
return adapter.cast(this);
if (adapter.isAssignableFrom(Element.class)) {
return adapter.cast(implementation);
} else if (IMarkerRefCounter.class.equals(adapter)) {
return adapter.cast(getMarkerRefCounter());
} else if (ILabelRefCounter.class.equals(adapter)) {
return adapter.cast(getLabelRefCounter());
} else if (ICoreEventSupport.class.equals(adapter)) {
return adapter.cast(getCoreEventSupport());
}
return super.getAdapter(adapter);
}
/**
* @see org.xmind.core.internal.Sheet#getLocalTitleText()
*/
@Override
protected String getLocalTitleText() {
return DOMUtils.getTextContentByTag(implementation, TAG_TITLE);
}
/**
* @see org.xmind.core.ITitled#setTitleText(java.lang.String)
*/
public void setTitleText(String titleText) {
String oldValue = getLocalTitleText();
DOMUtils.setText(implementation, TAG_TITLE, titleText);
String newValue = getLocalTitleText();
fireValueChange(Core.TitleText, oldValue, newValue);
updateModificationInfo();
}
/**
* @see org.xmind.core.ISheet#getRootTopic()
*/
public ITopic getRootTopic() {
Element t = DOMUtils.getFirstChildElementByTag(implementation,
TAG_TOPIC);
return (ITopic) ownedWorkbook.getAdaptableRegistry().getAdaptable(t);
}
/**
* @see org.xmind.core.ISheet#getId()
*/
public String getId() {
return implementation.getAttribute(ATTR_ID);
}
public IWorkbook getOwnedWorkbook() {
return ownedWorkbook;
}
/*
* (non-Javadoc)
* @see org.xmind.core.IWorkbookComponent#isOrphan()
*/
public boolean isOrphan() {
return DOMUtils.isOrphanNode(implementation);
}
/**
* @see org.xmind.core.ISheet#getParent()
*/
public IWorkbook getParent() {
Node p = implementation.getParentNode();
if (p == ownedWorkbook.getWorkbookElement())
return ownedWorkbook;
return null;
}
/**
* @see org.xmind.core.ISheet#getIndex()
*/
public int getIndex() {
Node p = implementation.getParentNode();
if (p == ownedWorkbook.getWorkbookElement()) {
return DOMUtils.getElementIndex(p, DOMConstants.TAG_SHEET,
implementation);
}
return -1;
}
/**
* @see org.xmind.core.ISheet#getRelationships()
*/
public Set<IRelationship> getRelationships() {
Element rs = DOMUtils.getFirstChildElementByTag(implementation,
TAG_RELATIONSHIPS);
if (rs != null)
return DOMUtils.getChildSet(rs, TAG_RELATIONSHIP,
ownedWorkbook.getAdaptableRegistry());
return NO_RELATIONSHIPS;
}
/**
* @see org.xmind.core.ISheet#addRelationship(org.xmind.core.IRelationship)
*/
public void addRelationship(IRelationship rel) {
Element rs = DOMUtils.ensureChildElement(implementation,
TAG_RELATIONSHIPS);
Element r = ((RelationshipImpl) rel).getImplementation();
Node n = rs.appendChild(r);
if (n != null) {
if (!isOrphan()) {
((RelationshipImpl) rel).addNotify(ownedWorkbook, this);
}
fireTargetChange(Core.RelationshipAdd, rel);
}
}
/**
* @see org.xmind.core.ISheet#removeRelationship(org.xmind.core.IRelationship)
*/
public void removeRelationship(IRelationship rel) {
Element rs = DOMUtils.getFirstChildElementByTag(implementation,
TAG_RELATIONSHIPS);
if (rs != null) {
if (!isOrphan()) {
((RelationshipImpl) rel).removeNotify(ownedWorkbook, this);
}
Element r = ((RelationshipImpl) rel).getImplementation();
Node n = rs.removeChild(r);
if (!rs.hasChildNodes())
implementation.removeChild(rs);
if (n != null) {
fireTargetChange(Core.RelationshipRemove, rel);
updateModificationInfo();
}
}
}
public String getThemeId() {
return DOMUtils.getAttribute(implementation, ATTR_THEME);
}
public void setThemeId(String themeId) {
String oldValue = getThemeId();
WorkbookImpl workbook = (WorkbookImpl) getParent();
decreaseThemeRef(workbook);
DOMUtils.setAttribute(implementation, ATTR_THEME, themeId);
increaseThemeRef(workbook);
String newValue = getThemeId();
fireValueChange(Core.ThemeId, oldValue, newValue);
updateModificationInfo();
}
public String getStyleId() {
return DOMUtils.getAttribute(implementation, ATTR_STYLE_ID);
}
public void setStyleId(String styleId) {
String oldValue = getStyleId();
WorkbookImpl workbook = (WorkbookImpl) getParent();
WorkbookUtilsImpl.decreaseStyleRef(workbook, this);
DOMUtils.setAttribute(implementation, ATTR_STYLE_ID, styleId);
WorkbookUtilsImpl.increaseStyleRef(workbook, this);
String newValue = getStyleId();
fireValueChange(Core.Style, oldValue, newValue);
updateModificationInfo();
}
public void replaceRootTopic(ITopic newRootTopic) {
TopicImpl r1 = (TopicImpl) getRootTopic();
TopicImpl r2 = (TopicImpl) newRootTopic;
if (!isOrphan()) {
r1.removeNotify((WorkbookImpl) getParent(), this, null);
}
implementation.removeChild(r1.getImplementation());
implementation.appendChild(r2.getImplementation());
if (!isOrphan()) {
r2.addNotify((WorkbookImpl) getParent(), this, null);
}
fireValueChange(Core.RootTopic, r1, r2);
updateModificationInfo();
}
public ILegend getLegend() {
if (legend == null) {
legend = new LegendImpl(implementation, this);
}
return legend;
}
public ILabelRefCounter getLabelRefCounter() {
if (labelRefCounter == null)
labelRefCounter = new SheetLabelRefCounter(this);
return labelRefCounter;
}
public IMarkerRefCounter getMarkerRefCounter() {
if (markerRefCounter == null)
markerRefCounter = new SheetMarkerRefCounter(this);
return markerRefCounter;
}
protected void addNotify(WorkbookImpl workbook) {
getImplementation().setIdAttribute(DOMConstants.ATTR_ID, true);
workbook.getAdaptableRegistry().registerById(this, getId(),
getImplementation().getOwnerDocument());
WorkbookUtilsImpl.increaseStyleRef(workbook, this);
increaseThemeRef(workbook);
((TopicImpl) getRootTopic()).addNotify(workbook, this, null);
for (IRelationship rel : getRelationships()) {
((RelationshipImpl) rel).addNotify(workbook, this);
}
}
protected void removeNotify(WorkbookImpl workbook) {
for (IRelationship rel : getRelationships()) {
((RelationshipImpl) rel).removeNotify(workbook, this);
}
((TopicImpl) getRootTopic()).removeNotify(workbook, this, null);
decreaseThemeRef(workbook);
WorkbookUtilsImpl.decreaseStyleRef(workbook, this);
workbook.getAdaptableRegistry().unregisterById(this, getId(),
getImplementation().getOwnerDocument());
getImplementation().setIdAttribute(DOMConstants.ATTR_ID, false);
}
private void decreaseThemeRef(WorkbookImpl workbook) {
if (workbook == null)
return;
String themeId = getThemeId();
if (themeId != null)
workbook.getStyleRefCounter().decreaseRef(themeId);
}
private void increaseThemeRef(WorkbookImpl workbook) {
if (workbook == null)
return;
String themeId = getThemeId();
if (themeId != null)
workbook.getStyleRefCounter().increaseRef(themeId);
}
public ICoreEventSupport getCoreEventSupport() {
return ownedWorkbook.getCoreEventSupport();
}
public ICoreEventRegistration registerCoreEventListener(String type,
ICoreEventListener listener) {
return getCoreEventSupport().registerCoreEventListener(this, type,
listener);
}
private void fireValueChange(String type, Object oldValue,
Object newValue) {
ICoreEventSupport coreEventSupport = getCoreEventSupport();
if (coreEventSupport != null) {
coreEventSupport.dispatchValueChange(this, type, oldValue,
newValue);
}
}
private void fireTargetChange(String type, Object target) {
ICoreEventSupport coreEventSupport = getCoreEventSupport();
if (coreEventSupport != null) {
coreEventSupport.dispatchTargetChange(this, type, target);
}
}
public long getModifiedTime() {
return InternalDOMUtils.getModifiedTime(this, implementation);
}
public String getModifiedBy() {
return InternalDOMUtils.getModifiedBy(this, implementation);
}
protected void updateModificationInfo() {
InternalDOMUtils.updateModificationInfo(this);
IWorkbook parent = getParent();
if (parent != null) {
((WorkbookImpl) parent).updateModificationInfo();
}
}
public ISheetSetting getSetting() {
if (setting == null)
setting = new SheetSetting(implementation, this);
return setting;
}
public ISheetSettings getSettings() {
if (settings == null)
settings = new SheetSettingsImpl(implementation, this);
return settings;
}
}