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    package org.apache.camel.view;
018    
019    import java.util.ArrayList;
020    import java.util.List;
021    
022    import org.apache.camel.model.AggregatorType;
023    import org.apache.camel.model.BeanRef;
024    import org.apache.camel.model.ChoiceType;
025    import org.apache.camel.model.FilterType;
026    import org.apache.camel.model.FromType;
027    import org.apache.camel.model.OtherwiseType;
028    import org.apache.camel.model.ProcessorType;
029    import org.apache.camel.model.RecipientListType;
030    import org.apache.camel.model.ResequencerType;
031    import org.apache.camel.model.RoutingSlipType;
032    import org.apache.camel.model.SplitterType;
033    import org.apache.camel.model.ToType;
034    import org.apache.camel.model.WhenType;
035    
036    import static org.apache.camel.util.ObjectHelper.isNotNullAndNonEmpty;
037    import static org.apache.camel.util.ObjectHelper.isNullOrBlank;
038    
039    /**
040     * Represents a node in the EIP diagram tree
041     *
042     * @version $Revision: 1501 $
043     */
044    public class NodeData {
045        public String id;
046        public String image;
047        public String label;
048        public String shape;
049        public String edgeLabel;
050        public String tooltop;
051        public String nodeType;
052        public boolean nodeWritten;
053        public String url;
054        public List<ProcessorType> outputs;
055        public String association = "property";
056        private final String imagePrefix;
057    
058        public NodeData(String id, Object node, String imagePrefix) {
059            this.id = id;
060            this.imagePrefix = imagePrefix;
061    
062            if (node instanceof ProcessorType) {
063                ProcessorType processorType = (ProcessorType)node;
064                this.edgeLabel = processorType.getLabel();
065            }
066            if (node instanceof FromType) {
067                FromType fromType = (FromType)node;
068                this.tooltop = fromType.getLabel();
069                this.label = removeQueryString(this.tooltop);
070                this.url = "http://activemq.apache.org/camel/message-endpoint.html";
071            } else if (node instanceof ToType) {
072                ToType toType = (ToType)node;
073                this.tooltop = toType.getLabel();
074                this.label = removeQueryString(this.tooltop);
075                this.edgeLabel = "";
076                this.url = "http://activemq.apache.org/camel/message-endpoint.html";
077            } else if (node instanceof FilterType) {
078                this.image = imagePrefix + "MessageFilterIcon.png";
079                this.label = "Filter";
080                this.nodeType = "Message Filter";
081            } else if (node instanceof WhenType) {
082                this.image = imagePrefix + "MessageFilterIcon.png";
083                this.nodeType = "When Filter";
084                this.label = "When";
085                this.url = "http://activemq.apache.org/camel/content-based-router.html";
086            } else if (node instanceof OtherwiseType) {
087                this.nodeType = "Otherwise";
088                this.edgeLabel = "";
089                this.url = "http://activemq.apache.org/camel/content-based-router.html";
090                this.tooltop = "Otherwise";
091            } else if (node instanceof ChoiceType) {
092                this.image = imagePrefix + "ContentBasedRouterIcon.png";
093                this.nodeType = "Content Based Router";
094                this.label = "Choice";
095                this.edgeLabel = "";
096    
097                ChoiceType choice = (ChoiceType)node;
098                List<ProcessorType> outputs = new ArrayList<ProcessorType>(choice.getWhenClauses());
099                if (choice.getOtherwise() != null) {
100                    outputs.add(choice.getOtherwise());
101                }
102                this.outputs = outputs;
103            } else if (node instanceof RecipientListType) {
104                this.image = imagePrefix + "RecipientListIcon.png";
105                this.nodeType = "Recipient List";
106            } else if (node instanceof RoutingSlipType) {
107                this.image = imagePrefix + "RoutingTableIcon.png";
108                this.nodeType = "Routing Slip";
109                this.url = "http://activemq.apache.org/camel/routing-slip.html";
110                this.tooltop = ((RoutingSlipType) node).getHeaderName();
111            } else if (node instanceof SplitterType) {
112                this.image = imagePrefix + "SplitterIcon.png";
113                this.nodeType = "Splitter";
114            } else if (node instanceof AggregatorType) {
115                this.image = imagePrefix + "AggregatorIcon.png";
116                this.nodeType = "Aggregator";
117            } else if (node instanceof ResequencerType) {
118                this.image = imagePrefix + "ResequencerIcon.png";
119                this.nodeType = "Resequencer";
120            } else if (node instanceof BeanRef) {
121                BeanRef beanRef = (BeanRef) node;
122    
123                // TODO
124                //this.image = imagePrefix + "Bean.png";
125                this.nodeType = "Bean Ref";
126                this.label = beanRef.getLabel() + " Bean"; 
127                this.shape = "box";
128            }
129    
130            // lets auto-default as many values as we can
131            if (isNullOrBlank(this.nodeType) && node != null) {
132                // TODO we could add this to the model?
133                String name = node.getClass().getName();
134                int idx = name.lastIndexOf('.');
135                if (idx > 0) {
136                    name = name.substring(idx + 1);
137                }
138                if (name.endsWith("Type")) {
139                    name = name.substring(0, name.length() - 4);
140                }
141                this.nodeType = insertSpacesBetweenCamelCase(name);
142            }
143            if (this.label == null) {
144                if (isNullOrBlank(this.image)) {
145                    this.label = this.nodeType;
146                    this.shape = "box";
147                } else if (isNotNullAndNonEmpty(this.edgeLabel)) {
148                    this.label = "";
149                } else {
150                    this.label = node.toString();
151                }
152            }
153            if (isNullOrBlank(this.tooltop)) {
154                if (isNotNullAndNonEmpty(this.nodeType)) {
155                    String description = isNotNullAndNonEmpty(this.edgeLabel) ? this.edgeLabel : this.label;
156                    this.tooltop = this.nodeType + ": " + description;
157                } else {
158                    this.tooltop = this.label;
159                }
160            }
161            if (isNullOrBlank(this.url) && isNotNullAndNonEmpty(this.nodeType)) {
162                this.url = "http://activemq.apache.org/camel/" + this.nodeType.toLowerCase().replace(' ', '-')
163                           + ".html";
164            }
165            if (node instanceof ProcessorType && this.outputs == null) {
166                ProcessorType processorType = (ProcessorType)node;
167                this.outputs = processorType.getOutputs();
168            }
169        }
170    
171        protected String removeQueryString(String text) {
172            int idx = text.indexOf("?");
173            if (idx <= 0) {
174                return text;
175            } else {
176                return text.substring(0, idx);
177            }
178        }
179    
180        /**
181         * Lets insert a space before each upper case letter after a lowercase
182         */
183        public static String insertSpacesBetweenCamelCase(String name) {
184            boolean lastCharacterLowerCase = false;
185            StringBuffer buffer = new StringBuffer();
186            int i = 0;
187            for (int size = name.length(); i < size; i++) {
188                char ch = name.charAt(i);
189                if (Character.isUpperCase(ch)) {
190                    if (lastCharacterLowerCase) {
191                        buffer.append(' ');
192                    }
193                    lastCharacterLowerCase = false;
194                } else {
195                    lastCharacterLowerCase = true;
196                }
197                buffer.append(ch);
198            }
199            return buffer.toString();
200        }
201    }