All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.xmind.core.internal.dom.StyleImpl Maven / Gradle / Ivy

/* ******************************************************************************
 * 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_NAME;
import static org.xmind.core.internal.dom.DOMConstants.ATTR_STYLE_FAMILY;
import static org.xmind.core.internal.dom.DOMConstants.ATTR_STYLE_ID;
import static org.xmind.core.internal.dom.DOMConstants.ATTR_TYPE;
import static org.xmind.core.internal.dom.DOMConstants.TAG_DEFAULT_STYLE;
import static org.xmind.core.internal.dom.DOMConstants.TAG_PROPERTIES;

import java.util.Iterator;
import java.util.Properties;

import org.w3c.dom.Attr;
import org.w3c.dom.Element;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.xmind.core.Core;
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.Style;
import org.xmind.core.style.IStyleSheet;
import org.xmind.core.util.DOMUtils;
import org.xmind.core.util.Property;

public class StyleImpl extends Style implements ICoreEventSource {

    private final class PropertyIter implements Iterator {

        Iterator it = propertiesElementIter();

        Element propEle = it.next();

        NamedNodeMap map = propEle == null ? null : propEle.getAttributes();

        int index = 0;

        Property next = findNextProperty();

        private Property findNextProperty() {
            if (map != null) {
                if (index < map.getLength()) {
                    Attr attr = (Attr) map.item(index);
                    index++;
                    return new Property(attr.getName(), attr.getValue());
                }
                if (it.hasNext()) {
                    propEle = it.next();
                    map = propEle == null ? null : propEle.getAttributes();
                    index = 0;
                    if (map != null) {
                        return findNextProperty();
                    }
                }
            }
            return null;
        }

        public void remove() {
        }

        public Property next() {
            if (next == null)
                return next;

            Property result = next;
            next = findNextProperty();
            return result;
        }

        public boolean hasNext() {
            return next != null;
        }
    }

    private final class DefaultStyleIter implements Iterator {

        Iterator propEleIt = propertiesElementIter();

        Element propEle = null;

        Iterator defaultStyleEleIt = null;

        Property next = findNextDefaultStyle();

        private Property findNextDefaultStyle() {
            if (defaultStyleEleIt != null) {
                while (defaultStyleEleIt.hasNext()) {
                    Element defaultStyleEle = defaultStyleEleIt.next();
                    String family = DOMUtils.getAttribute(defaultStyleEle,
                            ATTR_STYLE_FAMILY);
                    if (family != null) {
                        String styleId = DOMUtils.getAttribute(defaultStyleEle,
                                ATTR_STYLE_ID);
                        return new Property(family, styleId);
                    }
                }
            }
            if (propEleIt.hasNext()) {
                propEle = propEleIt.next();
                defaultStyleEleIt = DOMUtils.childElementIterByTag(propEle,
                        TAG_DEFAULT_STYLE);
                return findNextDefaultStyle();
            }
            return null;
        }

        public boolean hasNext() {
            return next != null;
        }

        public Property next() {
            if (next == null)
                return next;

            Property result = next;
            next = findNextDefaultStyle();
            return result;
        }

        public void remove() {
        }

    }

    private Element implementation;

    private StyleSheetImpl ownedSheet;

    public StyleImpl(Element implementation, StyleSheetImpl ownedSheet) {
        this.implementation = DOMUtils.addIdAttribute(implementation);
        this.ownedSheet = ownedSheet;
    }

    public String getId() {
        return implementation.getAttribute(DOMConstants.ATTR_ID);
    }

    public String getType() {
        return implementation.getAttribute(ATTR_TYPE);
    }

    public Element getImplementation() {
        return implementation;
    }

    public boolean equals(Object obj) {
        if (obj == this)
            return true;
        if (obj == null || !(obj instanceof StyleImpl))
            return false;
        StyleImpl that = (StyleImpl) obj;
        return this.implementation == that.implementation;
    }

    public int hashCode() {
        return implementation.hashCode();
    }

    public String toString() {
        return "STY#" + getId() + "(" + getName() + ")"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
    }

    public Object getAdapter(Class adapter) {
        if (adapter == Element.class || adapter == Node.class)
            return implementation;
        return super.getAdapter(adapter);
    }

    public IStyleSheet getOwnedStyleSheet() {
        return ownedSheet;
    }

    public String getName() {
        String name = implementation.getAttribute(ATTR_NAME);
        if (name.startsWith("%")) { //$NON-NLS-1$
            Properties properties = ownedSheet.getProperties();
            if (properties != null) {
                String key = name.substring(1);
                name = properties.getProperty(key, name);
            }
        }
        return name;
    }

//    public Properties getProperties() {
//        Properties prop = new Properties();
//        Iterator it = propertiesElementsIter();
//        while (it.hasNext()) {
//            Element propEle = it.next();
//            NamedNodeMap attrs = propEle.getAttributes();
//            for (int i = 0; i < attrs.getLength(); i++) {
//                Attr attr = (Attr) attrs.item(i);
//                prop.setProperty(attr.getName(), attr.getValue());
//            }
//        }
//        return prop;
//    }

    public String getProperty(String key) {
        Iterator it = propertiesElementIter();
        while (it.hasNext()) {
            String value = DOMUtils.getAttribute(it.next(), key);
            if (value != null)
                return value;
        }
        return null;
    }

    private Iterator propertiesElementIter() {
        return DOMUtils.childElementIterByTag(implementation,
                getPropertiesElementName());
    }

    public void setProperty(String key, String value) {
        String oldValue = getProperty(key);
        String propEleName = getPropertiesElementName();
        Element p = DOMUtils.ensureChildElement(implementation, propEleName);
        DOMUtils.setAttribute(p, key, value);
        String newValue = getProperty(key);
        firePropertyChange(key, oldValue, newValue);
    }

    private String getPropertiesElementName() {
        return getType().toLowerCase() + "-" + TAG_PROPERTIES; //$NON-NLS-1$
    }

    public int size() {
        Iterator it = propertiesElementIter();
        int size = 0;
        while (it.hasNext()) {
            size += it.next().getAttributes().getLength();
        }
        return size;
    }

    public boolean isEmpty() {
        Iterator it = propertiesElementIter();
        while (it.hasNext()) {
            Element propEle = it.next();
            if (propEle.hasAttributes() || propEle.hasChildNodes())
                return false;
        }
        return true;
    }

    public Iterator properties() {
        return new PropertyIter();
    }

    public void setName(String name) {
        String oldValue = implementation.hasAttribute(ATTR_NAME) ? getName()
                : null;
        DOMUtils.setAttribute(implementation, ATTR_NAME, name);
        String newValue = implementation.hasAttribute(ATTR_NAME) ? getName()
                : null;
        fireValueChange(Core.Name, oldValue, newValue);
    }

    public Iterator defaultStyles() {
        return new DefaultStyleIter();
    }

    public String getDefaultStyleId(String styleFamily) {
        if (styleFamily == null || "".equals(styleFamily)) //$NON-NLS-1$
            return null;
        Iterator it = propertiesElementIter();
        while (it.hasNext()) {
            Iterator it2 = DOMUtils.childElementIterByTag(it.next(),
                    TAG_DEFAULT_STYLE);
            while (it2.hasNext()) {
                Element ds = it2.next();
                if (styleFamily.equals(ds.getAttribute(ATTR_STYLE_FAMILY))) {
                    return DOMUtils.getAttribute(ds, ATTR_STYLE_ID);
                }
            }
        }
        return null;
    }

    public void setDefaultStyleId(String styleFamily, String styleId) {
        if (styleFamily == null || "".equals(styleFamily)) //$NON-NLS-1$
            return;

        String propEleName = getPropertiesElementName();
        if (styleId != null) {
            Element p = DOMUtils
                    .ensureChildElement(implementation, propEleName);
            Element ds = findDefaultStyleElement(p, styleFamily);
            if (ds == null) {
                ds = DOMUtils.createElement(p, TAG_DEFAULT_STYLE);
                DOMUtils.setAttribute(ds, ATTR_STYLE_FAMILY, styleFamily);
            }
            DOMUtils.setAttribute(ds, ATTR_STYLE_ID, styleId);
        } else {
            Element p = DOMUtils.getFirstChildElementByTag(implementation,
                    propEleName);
            if (p != null) {
                Element ds = findDefaultStyleElement(p, styleFamily);
                if (ds != null) {
                    Node n = p.removeChild(ds);
                    if (n != null) {
                        if (!p.hasChildNodes()) {
                            implementation.removeChild(p);
                        }
                    }
                }
            }
        }
    }

    private Element findDefaultStyleElement(Element propEle, String styleFamily) {
        Iterator it = DOMUtils.childElementIterByTag(propEle,
                TAG_DEFAULT_STYLE);
        while (it.hasNext()) {
            Element ds = it.next();
            if (styleFamily.equals(ds.getAttribute(ATTR_STYLE_FAMILY))) {
                return ds;
            }
        }
        return null;
    }

//    public boolean contentEquals(IStyle style) {
//        StyleImpl s = (StyleImpl) style;
//        if (!getType().equals(s.getType()))
//            return false;
//
//        int propSize = 0;
//        int dsSize = 0;
//
//        Iterator it = propertiesElementIter();
//        while (it.hasNext()) {
//            Element propEle = it.next();
//            NamedNodeMap attrs = propEle.getAttributes();
//            for (int i = 0; i < attrs.getLength(); i++) {
//                Node attr = attrs.item(i);
//                String key = attr.getNodeName();
//                String value = attr.getNodeValue();
//                if (!value.equals(s.getProperty(key)))
//                    return false;
//            }
//            Iterator dsIt = DOMUtils.childElementIterByTag(propEle,
//                    TAG_DEFAULT_STYLE);
//            while (dsIt.hasNext()) {
//                
//            }
//        }
//
//        return true;
//    }
//
//    public int getParentGroupId() {
//        Node p = implementation.getParentNode();
//        if (p != null && p instanceof Element) {
//            Element g = (Element) p;
//            String name = g.getTagName();
//            if (DOMConstants.TAG_STYLES.equals(name))
//                return IStyleSheet.GROUP_NORMAL;
//            if (DOMConstants.TAG_MASTER_STYLES.equals(name))
//                return IStyleSheet.GROUP_MASTER;
//            if (DOMConstants.TAG_AUTOMATIC_STYLES.equals(name))
//                return IStyleSheet.GROUP_AUTOMATIC;
//        }
//        return IStyleSheet.GROUP_NONE;
//    }

    public ICoreEventRegistration registerCoreEventListener(String type,
            ICoreEventListener listener) {
        return getCoreEventSupport().registerCoreEventListener(this, type,
                listener);
    }

    private void fireValueChange(String eventType, Object oldValue,
            Object newValue) {
        getCoreEventSupport().dispatchValueChange(this, eventType, oldValue,
                newValue);
    }

    private void firePropertyChange(String key, String oldValue, String newValue) {
        getCoreEventSupport().dispatchTargetValueChange(this, Core.Property,
                key, oldValue, newValue);
    }

    public ICoreEventSupport getCoreEventSupport() {
        return ownedSheet.getCoreEventSupport();
    }

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy