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: 41895 $
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    }