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