/*******************************************************************************
* 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();
}
}