/******************************************************************************* * Copyright (c) 2007 Exadel, Inc. and Red Hat, Inc. * Distributed under license by Red Hat, Inc. All rights reserved. * This program is 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: * Exadel, Inc. and Red Hat, Inc. - initial API and implementation ******************************************************************************/ package org.jboss.tools.jsf.ui.editor.model.impl; import java.util.*; import java.util.List; import org.eclipse.draw2d.geometry.Point; import org.eclipse.draw2d.geometry.PointList; import org.eclipse.swt.widgets.*; import org.jboss.tools.common.model.*; import org.jboss.tools.jsf.ui.editor.model.IPage; import org.jboss.tools.jsf.ui.editor.model.IJSFElement; import org.jboss.tools.jsf.ui.editor.model.ILink; import org.jboss.tools.jsf.ui.editor.model.ILinkListener; import org.jboss.tools.jsf.ui.editor.model.IGroup; import org.jboss.tools.jsf.ui.editor.model.ISegment; public class Link extends JSFElement implements ILink { public static final String PATH_PROPERTY = "link shape"; //$NON-NLS-1$ public static final String SHAPE_PROPERTY = "shape"; //$NON-NLS-1$ public static final String HIDDEN_PROPERTY = "hidden"; //$NON-NLS-1$ private String pathString; private String linkStatus; private boolean preferredMode = false; private int preferredLength = 0; List<ILinkListener> linkListeners = new Vector<ILinkListener>(); XModelObject target = null; IGroup toGroup; ISegment headSegment; ISegment tailSegment; public void dispose() { super.dispose(); if (linkListeners != null) linkListeners.clear(); linkListeners = null; } public boolean isPreferredMode() { return preferredMode; } public int getPreferredLength() { if (preferredMode) return preferredLength; else return 0; } public String getPathFromModel() { if (preferredMode) return ""; //$NON-NLS-1$ else { return source.getAttributeValue(Link.SHAPE_PROPERTY); } } public PointList getPointList() { int[] path = null; pathString = source.getAttributeValue(SHAPE_PROPERTY); path = jsfModel.getHelper().asIntArray(source, SHAPE_PROPERTY); PointList list = new PointList(); if (path.length < 4) return list; for (int i = 0; i < path.length; i += 2) { list.addPoint(path[i], path[i + 1]); } return list; } public void savePointList(PointList list) { String value = ""; //$NON-NLS-1$ for (int i = 0; i < list.size(); i++) { if (i != 0) value += ","; //$NON-NLS-1$ Point p = list.getPoint(i); value += p.x + "," + p.y; //$NON-NLS-1$ } jsfModel.getHelper().setAttributeValue(source, SHAPE_PROPERTY, value); } public void clearPointList() { source.setAttributeValue(SHAPE_PROPERTY, ""); //$NON-NLS-1$ } public Link(IJSFElement parent, XModelObject source) { super(parent, source); target = getJSFModel().getHelper().getItemOutputTarget(source); int[] path = null; pathString = source.getAttributeValue(SHAPE_PROPERTY); path = jsfModel.getHelper().asIntArray(source, SHAPE_PROPERTY); linkStatus = getLinkStatus(); if (path.length > 1 && path[0] == -1) { preferredMode = true; preferredLength = path[1]; path = new int[] {}; } else preferredMode = false; Segment prevSegment = null; for (int i = 0; i < path.length; i++) { Segment newSegment = new Segment(this, path[i], prevSegment); if (i == 0) headSegment = newSegment; if (i == path.length - 1) tailSegment = newSegment; prevSegment = newSegment; } } public void setTarget() { if (target == null) { return; } if (target.getPath() == null) { return; } toGroup = (IGroup) jsfModel.findElement(target.getPath()); if (toGroup != null) { ((Group) toGroup).addInputLink(this); ((Page) getParentJSFElement()).fireLinkAdd(this); } } public XModelObject getTargetModel() { return target; } public Menu getPopupMenu(Control control, Object environment) { if (getSource() == null) return null; return null; } public String getLinkName() { return getJSFModel().getHelper().getItemOutputPresentation(source); } public IGroup getToGroup() { return toGroup; } public IPage getFromPage() { return (IPage) getParentJSFElement(); } public IGroup getFromGroup() { return getFromPage().getGroup(); } public boolean isShortcut() { return jsfModel.getHelper().isShortcut(source); } public boolean isConfirmed() { if (((Group) getFromGroup()).type.equals("page")) { //$NON-NLS-1$ String subtype = source.getAttributeValue(Link.SUBTYPE_PROPERTY); if ("confirmed".equals(subtype)) //$NON-NLS-1$ return true; else return false; } return true; } public boolean isHidden() { String hidden = source.getAttributeValue(Link.HIDDEN_PROPERTY); if ("yes".equals(hidden)) //$NON-NLS-1$ return true; else return false; } public void remove() { } public void addLinkListener(ILinkListener l) { linkListeners.add(l); } public void removeLinkListener(ILinkListener l) { linkListeners.remove(l); } public ISegment getHeadSegment() { return headSegment; } public ISegment getTailSegment() { return tailSegment; } public void setHeadSegment(ISegment segment) { ISegment oldHeadSegment = headSegment; headSegment = (ISegment) segment; propertyChangeSupport.firePropertyChange("headSegment", oldHeadSegment, //$NON-NLS-1$ segment); } public void setTailSegment(ISegment segment) { ISegment oldTailSegment = tailSegment; tailSegment = (ISegment) segment; propertyChangeSupport.firePropertyChange("tailSegment", oldTailSegment, //$NON-NLS-1$ segment); } public ISegment createSegment(int length, ISegment prevSegment) { ISegment newSegment = new Segment(this, length, prevSegment); return newSegment; } public void fireLinkChange() { List<ILinkListener> targets = new ArrayList<ILinkListener>(); targets.addAll(linkListeners); for (int i = 0; i < targets.size(); i++) { ILinkListener listener = (ILinkListener) targets.get(i); if (listener != null) listener.linkChange(this); } } public void fireLinkRemove() { List<ILinkListener> targets = new ArrayList<ILinkListener>(); targets.addAll(linkListeners); for (int i = 0; i < targets.size(); i++) { ILinkListener listener = (ILinkListener) targets.get(i); if (listener != null) listener.linkRemove(this); } ((JSFModel) getJSFModel()).fireLinkRemove(this); } private String getLinkStatus() { return source.getAttributeValue(HIDDEN_PROPERTY) + ":" //$NON-NLS-1$ + source.getAttributeValue("shortcut"); //$NON-NLS-1$ } public void nodeChanged(Object eventData) { int[] path = null; if (target == null) { target = getJSFModel().getHelper().getItemOutputTarget(source); if (target != null) { setTarget(); } } else { if (!target.equals(getJSFModel().getHelper().getItemOutputTarget( source))) { if(toGroup != null) { ((Group) toGroup).removeInputLink(this); } target = getJSFModel().getHelper().getItemOutputTarget(source); setTarget(); fireLinkChange(); return; } } String temp, ls; ls = getLinkStatus(); temp = source.getAttributeValue(SHAPE_PROPERTY); path = jsfModel.getHelper().asIntArray(source, SHAPE_PROPERTY); if (pathString.equals(temp) && (linkStatus == null || linkStatus.equals(ls))) { fireLinkChange(); return; } if (path.length > 1 && path[0] == -1) { preferredMode = true; preferredLength = path[1]; path = new int[] {}; } else preferredMode = false; Segment prevSegment = null; for (int i = 0; i < path.length; i++) { Segment newSegment = new Segment(this, path[i], prevSegment); if (i == 0) headSegment = newSegment; if (i == path.length - 1) tailSegment = newSegment; prevSegment = newSegment; } pathString = temp; linkStatus = ls; fireLinkChange(); } }