001 /**
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements. See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache License, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License. You may obtain a copy of the License at
008 *
009 * http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017 /**
018 * Licensed to the Apache Software Foundation (ASF) under one or more
019 * contributor license agreements. See the NOTICE file distributed with
020 * this work for additional information regarding copyright ownership.
021 * The ASF licenses this file to You under the Apache License, Version 2.0
022 * (the "License"); you may not use this file except in compliance with
023 * the License. You may obtain a copy of the License at
024 *
025 * http://www.apache.org/licenses/LICENSE-2.0
026 *
027 * Unless required by applicable law or agreed to in writing, software
028 * distributed under the License is distributed on an "AS IS" BASIS,
029 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
030 * See the License for the specific language governing permissions and
031 * limitations under the License.
032 */
033 package org.apache.camel.view;
034
035
036 import java.util.ArrayList;
037 import java.util.List;
038
039 import org.apache.camel.model.AggregatorType;
040 import org.apache.camel.model.ChoiceType;
041 import org.apache.camel.model.FilterType;
042 import org.apache.camel.model.FromType;
043 import org.apache.camel.model.OtherwiseType;
044 import org.apache.camel.model.ProcessorType;
045 import org.apache.camel.model.RecipientListType;
046 import org.apache.camel.model.ResequencerType;
047 import org.apache.camel.model.RoutingSlipType;
048 import org.apache.camel.model.SplitterType;
049 import org.apache.camel.model.ToType;
050 import org.apache.camel.model.WhenType;
051
052 import static org.apache.camel.util.ObjectHelper.isNotNullAndNonEmpty;
053 import static org.apache.camel.util.ObjectHelper.isNullOrBlank;
054 /**
055 * Represents a node in the EIP diagram tree
056 *
057 * @version $Revision: 660216 $
058 */
059 public class NodeData {
060 public String id;
061 public String image;
062 public String label;
063 public String shape;
064 public String edgeLabel;
065 public String tooltop;
066 public String nodeType;
067 public boolean nodeWritten;
068 public String url;
069 public List<ProcessorType> outputs;
070 public String association = "property";
071 private final String imagePrefix;
072
073 public NodeData(String id, Object node, String imagePrefix) {
074 this.id = id;
075 this.imagePrefix = imagePrefix;
076
077 if (node instanceof ProcessorType) {
078 ProcessorType processorType = (ProcessorType)node;
079 this.edgeLabel = processorType.getLabel();
080 }
081 if (node instanceof FromType) {
082 FromType fromType = (FromType)node;
083 this.tooltop = fromType.getLabel();
084 this.label = removeQueryString(this.tooltop);
085 this.url = "http://activemq.apache.org/camel/message-endpoint.html";
086 } else if (node instanceof ToType) {
087 ToType toType = (ToType)node;
088 this.tooltop = toType.getLabel();
089 this.label = removeQueryString(this.tooltop);
090 this.edgeLabel = "";
091 this.url = "http://activemq.apache.org/camel/message-endpoint.html";
092 } else if (node instanceof FilterType) {
093 this.image = imagePrefix + "MessageFilterIcon.png";
094 this.nodeType = "Message Filter";
095 } else if (node instanceof WhenType) {
096 this.image = imagePrefix + "MessageFilterIcon.png";
097 this.nodeType = "When Filter";
098 this.url = "http://activemq.apache.org/camel/content-based-router.html";
099 } else if (node instanceof OtherwiseType) {
100 this.nodeType = "Otherwise";
101 this.edgeLabel = "";
102 this.url = "http://activemq.apache.org/camel/content-based-router.html";
103 this.tooltop = "Otherwise";
104 } else if (node instanceof ChoiceType) {
105 this.image = imagePrefix + "ContentBasedRouterIcon.png";
106 this.nodeType = "Content Based Router";
107 this.label = "";
108 this.edgeLabel = "";
109
110 ChoiceType choice = (ChoiceType)node;
111 List<ProcessorType> outputs = new ArrayList<ProcessorType>(choice.getWhenClauses());
112 if (choice.getOtherwise() != null) {
113 outputs.add(choice.getOtherwise());
114 }
115 this.outputs = outputs;
116 } else if (node instanceof RecipientListType) {
117 this.image = imagePrefix + "RecipientListIcon.png";
118 this.nodeType = "Recipient List";
119 } else if (node instanceof RoutingSlipType) {
120 this.image = imagePrefix + "RoutingTableIcon.png";
121 this.nodeType = "Routing Slip";
122 this.url = "http://activemq.apache.org/camel/routing-slip.html";
123 this.tooltop = ((RoutingSlipType) node).getHeaderName();
124 } else if (node instanceof SplitterType) {
125 this.image = imagePrefix + "SplitterIcon.png";
126 this.nodeType = "Splitter";
127 } else if (node instanceof AggregatorType) {
128 this.image = imagePrefix + "AggregatorIcon.png";
129 this.nodeType = "Aggregator";
130 } else if (node instanceof ResequencerType) {
131 this.image = imagePrefix + "ResequencerIcon.png";
132 this.nodeType = "Resequencer";
133 }
134
135 // lets auto-default as many values as we can
136 if (isNullOrBlank(this.nodeType) && node != null) {
137 // TODO we could add this to the model?
138 String name = node.getClass().getName();
139 int idx = name.lastIndexOf('.');
140 if (idx > 0) {
141 name = name.substring(idx + 1);
142 }
143 if (name.endsWith("Type")) {
144 name = name.substring(0, name.length() - 4);
145 }
146 this.nodeType = insertSpacesBetweenCamelCase(name);
147 }
148 if (this.label == null) {
149 if (isNullOrBlank(this.image)) {
150 this.label = this.nodeType;
151 this.shape = "box";
152 } else if (isNotNullAndNonEmpty(this.edgeLabel)) {
153 this.label = "";
154 } else {
155 this.label = node.toString();
156 }
157 }
158 if (isNullOrBlank(this.tooltop)) {
159 if (isNotNullAndNonEmpty(this.nodeType)) {
160 String description = isNotNullAndNonEmpty(this.edgeLabel) ? this.edgeLabel : this.label;
161 this.tooltop = this.nodeType + ": " + description;
162 } else {
163 this.tooltop = this.label;
164 }
165 }
166 if (isNullOrBlank(this.url) && isNotNullAndNonEmpty(this.nodeType)) {
167 this.url = "http://activemq.apache.org/camel/" + this.nodeType.toLowerCase().replace(' ', '-')
168 + ".html";
169 }
170 if (node instanceof ProcessorType && this.outputs == null) {
171 ProcessorType processorType = (ProcessorType)node;
172 this.outputs = processorType.getOutputs();
173 }
174 }
175
176 protected String removeQueryString(String text) {
177 int idx = text.indexOf("?");
178 if (idx <= 0) {
179 return text;
180 } else {
181 return text.substring(0, idx);
182 }
183 }
184
185 /**
186 * Lets insert a space before each upper case letter after a lowercase
187 */
188 public static String insertSpacesBetweenCamelCase(String name) {
189 boolean lastCharacterLowerCase = false;
190 StringBuffer buffer = new StringBuffer();
191 int i = 0;
192 for (int size = name.length(); i < size; i++) {
193 char ch = name.charAt(i);
194 if (Character.isUpperCase(ch)) {
195 if (lastCharacterLowerCase) {
196 buffer.append(' ');
197 }
198 lastCharacterLowerCase = false;
199 } else {
200 lastCharacterLowerCase = true;
201 }
202 buffer.append(ch);
203 }
204 return buffer.toString();
205 }
206 }