KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > sslexplorer > extensions > ExtensionDescriptor


1 /*
2  * SSL-Explorer
3  *
4  * Copyright (C) 2003-2006 3SP LTD. All Rights Reserved
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * as published by the Free Software Foundation; either version 2 of
9  * the License, or (at your option) any later version.
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public
16  * License along with this program; if not, write to the Free Software
17  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18  */

19             
20 package com.sslexplorer.extensions;
21
22 import java.io.File JavaDoc;
23 import java.io.IOException JavaDoc;
24 import java.util.ArrayList JavaDoc;
25 import java.util.Collection JavaDoc;
26 import java.util.HashMap JavaDoc;
27 import java.util.HashSet JavaDoc;
28 import java.util.Iterator JavaDoc;
29 import java.util.List JavaDoc;
30 import java.util.Map JavaDoc;
31 import java.util.Set JavaDoc;
32
33 import org.apache.commons.logging.Log;
34 import org.apache.commons.logging.LogFactory;
35 import org.jdom.DataConversionException;
36 import org.jdom.Element;
37 import org.jdom.JDOMException;
38
39 import com.sslexplorer.boot.DefaultPropertyDefinitionCategory;
40 import com.sslexplorer.boot.PropertyClass;
41 import com.sslexplorer.boot.PropertyClassManager;
42 import com.sslexplorer.boot.PropertyDefinition;
43 import com.sslexplorer.boot.PropertyDefinitionCategory;
44 import com.sslexplorer.boot.Util;
45 import com.sslexplorer.boot.XMLPropertyDefinition;
46 import com.sslexplorer.core.CoreMessageResources;
47 import com.sslexplorer.core.CoreServlet;
48 import com.sslexplorer.core.CoreUtil;
49 import com.sslexplorer.properties.attributes.AttributesPropertyClass;
50 import com.sslexplorer.properties.attributes.XMLAttributeDefinition;
51 import com.sslexplorer.security.SessionInfo;
52
53 public class ExtensionDescriptor implements Comparable JavaDoc {
54
55     final static Log log = LogFactory.getLog(ExtensionDescriptor.class);
56
57     HashSet JavaDoc files;
58     HashMap JavaDoc parameters;
59     ExtensionType launcherType;
60     String JavaDoc typeName;
61     CoreMessageResources messageResources;
62     Element element;
63     Map JavaDoc tunnels;
64     String JavaDoc description;
65     String JavaDoc id;
66     String JavaDoc smallIcon;
67     String JavaDoc largeIcon;
68     String JavaDoc name;
69     ExtensionBundle bundle;
70     Element typeElement;
71     Element messagesElement;
72     Element propertyDefinitionsElement;
73     int status;
74     boolean hidden = false;
75     private List JavaDoc<String JavaDoc> messageKeys;
76     private Map JavaDoc<String JavaDoc, PropertyDefinition> propertyDefinitions;
77     private Map JavaDoc<Integer JavaDoc, PropertyDefinitionCategory> propertyDefinitionCategories;
78
79     public ExtensionDescriptor() {
80         this.files = new HashSet JavaDoc();
81         this.parameters = new HashMap JavaDoc();
82         this.tunnels = new HashMap JavaDoc();
83     }
84
85     public String JavaDoc getTypeName() {
86         return typeName;
87     }
88
89     public boolean isOptions() {
90         return parameters.size() > 0;
91     }
92
93     public boolean isHidden() {
94         return hidden;
95     }
96
97     public String JavaDoc getDescription() {
98         return description;
99     }
100
101     public void load(ExtensionBundle bundle, Element element) throws ExtensionException {
102
103         propertyDefinitions = new HashMap JavaDoc<String JavaDoc, PropertyDefinition>();
104         propertyDefinitionCategories = new HashMap JavaDoc<Integer JavaDoc, PropertyDefinitionCategory>();
105         messageKeys = new ArrayList JavaDoc<String JavaDoc>();
106
107         this.bundle = bundle;
108         this.element = element;
109
110         parameters.clear();
111         tunnels.clear();
112         files.clear();
113
114         if (log.isInfoEnabled())
115             log.info("Loading application descriptor");
116
117         String JavaDoc rootName = element.getName();
118         if (rootName.equals("application")) {
119             log.warn("DEPRECATED. Extension descriptor in " + bundle.getFile().getPath()
120                 + " should now have <extension> as the root element not <application>");
121         }
122
123         typeName = element.getAttribute("type").getValue();
124         if (typeName == null) {
125             throw new ExtensionException(ExtensionException.FAILED_TO_PROCESS_DESCRIPTOR, "<" + rootName
126                 + "> element requires attribute 'type'");
127         }
128
129         id = element.getAttributeValue("extension");
130
131         if (id == null) {
132             id = element.getAttributeValue("application");
133             if (id == null) {
134                 throw new ExtensionException(ExtensionException.FAILED_TO_PROCESS_DESCRIPTOR, "<" + element.getName()
135                     + "> element requires attribute 'application'");
136             } else {
137                 log.warn("DEPRECATED. In " + bundle.getFile().getPath() + ", <" + rootName
138                     + ">'s 'application' attribute should now be 'extension'");
139             }
140         }
141         if (log.isInfoEnabled())
142             log.info("Found extension descriptor " + getId());
143         if (!id.matches("^[a-zA-Z0-9_-]*$")) {
144             throw new ExtensionException(ExtensionException.FAILED_TO_PROCESS_DESCRIPTOR, "<" + element.getName() + "> attribute '"
145                 + id + "' may only contain word characters ([a-zA-Z_0-9]).");
146         }
147
148         name = element.getAttributeValue("name");
149         if (log.isDebugEnabled())
150             log.debug("Application name is " + name);
151         if (name == null) {
152             throw new ExtensionException(ExtensionException.FAILED_TO_PROCESS_DESCRIPTOR,
153                 "<application> element requires the attribute 'name'");
154         }
155         smallIcon = element.getAttributeValue("smallIcon");
156         largeIcon = element.getAttributeValue("largeIcon");
157
158         if (element.getAttribute("hidden") != null) {
159             try {
160                 hidden = element.getAttribute("hidden").getBooleanValue();
161             } catch (DataConversionException e) {
162                 throw new ExtensionException(ExtensionException.FAILED_TO_PROCESS_DESCRIPTOR, e);
163             }
164         }
165
166         messagesElement = null;
167         typeElement = null;
168
169         for (Iterator JavaDoc it = element.getChildren().iterator(); it.hasNext();) {
170             Element e = (Element) it.next();
171             if (e.getName().equalsIgnoreCase("description")) {
172                 description = e.getText();
173             } else if (e.getName().equalsIgnoreCase("parameter")) {
174                 addParameter(e);
175             } else if (e.getName().equalsIgnoreCase("messages")) {
176                 messagesElement = e;
177             } else if (e.getName().equalsIgnoreCase("tunnel")) {
178                 verifyTunnel(e);
179             } else if (e.getName().equalsIgnoreCase("files")) {
180                 verifyFiles(e);
181             } else if (e.getName().equals("propertyDefinitions")) {
182                 propertyDefinitionsElement = e;
183             } else if(e.getName().equals(typeName)){
184                 if(typeElement != null) {
185                     throw new ExtensionException(ExtensionException.FAILED_TO_PROCESS_DESCRIPTOR,
186                         "<" + e.getName() + "> must occur before type specific element.");
187                 }
188                 typeElement = e;
189             } else {
190                 /* Ignore elements that may be for client side only */
191             }
192         }
193
194         if(Util.isNullOrTrimmedBlank(description)) {
195             throw new ExtensionException(ExtensionException.FAILED_TO_PARSE_DESCRIPTOR,
196             "&lt;extension&gt; element must contain a &lt;description&gt;.");
197         }
198     }
199
200     public void start() throws ExtensionException {
201         /* Before starting this extension, we take a copy of
202          * all registered property definitions and categories
203          * in each class. If the extension fails to start in
204          * any way, the definitions will be rolled back
205          */

206         Map JavaDoc<PropertyClass,Collection JavaDoc<PropertyDefinition>> oldDefinitions = new HashMap JavaDoc<PropertyClass, Collection JavaDoc<PropertyDefinition>>();
207         Map JavaDoc<PropertyClass,Collection JavaDoc<PropertyDefinitionCategory>> oldCategories = new HashMap JavaDoc<PropertyClass, Collection JavaDoc<PropertyDefinitionCategory>>();
208         Collection JavaDoc<PropertyClass> oldPropertyClasses = PropertyClassManager.getInstance().getPropertyClasses();
209         try {
210             for(PropertyClass propertyClass : oldPropertyClasses) {
211                 try {
212                     propertyClass.store();
213                 } catch (IOException JavaDoc e) {
214                     throw new ExtensionException(ExtensionException.INTERNAL_ERROR, e, "Failed to store property class.");
215                 }
216             }
217         }
218         catch(ExtensionException ee) {
219             for(PropertyClass propertyClass : oldPropertyClasses) {
220                 propertyClass.reset();
221             }
222             throw ee;
223         }
224         
225         try {
226
227             // Load any message resources
228

229             try {
230                 if (messagesElement != null) {
231                     messageResources = CoreServlet.getServlet()
232                             .getExtensionStoreResources();
233                     for (Iterator JavaDoc i = messagesElement.getChildren().iterator(); i
234                             .hasNext();) {
235                         Element el = (Element) i.next();
236                         if (!el.getName().equals("message")) {
237                             throw new ExtensionException(
238                                     ExtensionException.FAILED_TO_PROCESS_DESCRIPTOR,
239                                     "<messages> element may only contain <message> elements.");
240                         }
241                         String JavaDoc key = el.getAttributeValue("key");
242                         if (key == null) {
243                             throw new ExtensionException(
244                                     ExtensionException.FAILED_TO_PROCESS_DESCRIPTOR,
245                                     "<message> element must have a key attribute.");
246                         }
247                         key = "application." + id + "." + key;
248                         messageKeys.add(key);
249                         messageResources
250                                 .setMessage(el.getAttributeValue("locale"),
251                                         key, el.getText());
252                     }
253                     messageResources.setMessage("", "application." + getId()
254                             + ".name", name);
255                 }
256
257                 // Load any definitions
258

259                 if (propertyDefinitionsElement != null) {
260                     for (Iterator JavaDoc ci = propertyDefinitionsElement.getChildren()
261                             .iterator(); ci.hasNext();) {
262                         Element c = (Element) ci.next();
263                         PropertyClassManager pcm = PropertyClassManager
264                                 .getInstance();
265                         PropertyClass pc = pcm.getPropertyClass(c.getName());
266                         if (pc == null) {
267                             throw new ExtensionException(
268                                     ExtensionException.INTERNAL_ERROR,
269                                     "No property definition class named "
270                                             + c.getName());
271                         }
272                         for (Iterator JavaDoc ei = c.getChildren().iterator(); ei
273                                 .hasNext();) {
274                             Element ec = (Element) ei.next();
275                             if (ec.getName().equals("definition")) {
276                                 PropertyDefinition def;
277                                 if (pc instanceof AttributesPropertyClass) {
278                                     def = new XMLAttributeDefinition(ec);
279                                 } else {
280                                     def = new XMLPropertyDefinition(ec);
281                                 }
282                                 propertyDefinitions.put(def.getName(), def);
283                                 pc.registerPropertyDefinition(def);
284                             } else if (ec.getName().equals("category")) {
285                                 PropertyDefinitionCategory cat = new DefaultPropertyDefinitionCategory(
286                                         ec.getAttribute("id").getIntValue(), ec
287                                                 .getAttributeValue("bundle"),
288                                         ec.getAttributeValue("image"));
289                                 cat.setPropertyClass(pc);
290                                 if (ec.getAttributeValue("parent") == null) {
291                                     pc.addPropertyDefinitionCategory(-1, cat);
292                                 } else {
293                                     PropertyDefinitionCategory parentCat = pc
294                                             .getPropertyDefinitionCategory(ec
295                                                     .getAttribute("parent")
296                                                     .getIntValue());
297                                     if (parentCat == null) {
298                                         throw new ExtensionException(
299                                                 ExtensionException.INTERNAL_ERROR,
300                                                 "No parent category for "
301                                                         + cat.getId()
302                                                         + " of "
303                                                         + ec
304                                                                 .getAttributeValue("parent"));
305                                     }
306                                     pc.addPropertyDefinitionCategory(parentCat
307                                             .getId(), cat);
308                                 }
309                                 propertyDefinitionCategories.put(cat.getId(),
310                                         cat);
311                             } else {
312                                 throw new ExtensionException(
313                                         ExtensionException.INTERNAL_ERROR,
314                                         "Expect child element of <definitions> with child elements of <definition>. Got <"
315                                                 + ec.getName() + ">.");
316                             }
317                         }
318                     }
319                 }
320             } catch (JDOMException e) {
321                 throw new ExtensionException(
322                         ExtensionException.FAILED_TO_PARSE_DESCRIPTOR, e,
323                         "Failed to parse descriptor.");
324             }
325
326             // Start the extension type
327

328             launcherType = ExtensionTypeManager.getInstance().getExtensionType(
329                     typeName, bundle);
330             launcherType.start(this, typeElement);
331             
332             // Reset stored property classes
333
for(PropertyClass propertyClass : oldPropertyClasses) {
334                 propertyClass.reset();
335             }
336             
337         } catch (Throwable JavaDoc ee) {
338             propertyDefinitionCategories.clear();
339             // Failed, so roll back definitions and categories
340
for (PropertyClass propertyClass : new ArrayList JavaDoc<PropertyClass>(PropertyClassManager
341                     .getInstance().getPropertyClasses())) {
342                 
343                 // The plugin may have registed property classes so they need to be removed
344
if(!oldPropertyClasses.contains(propertyClass)) {
345                     PropertyClassManager.getInstance().deregisterPropertyClass(propertyClass.getName());
346                 }
347                 else {
348                     try {
349                         propertyClass.restore();
350                     } catch (IOException JavaDoc e) {
351                         log.error("Extension failed for some reason, but SSL-Explorer cannot restore the property class. The original exception will follow.", ee);
352                         throw new ExtensionException(ExtensionException.INTERNAL_ERROR, e, "Failed to restore property class, this is fatal and no further extensions will correctly load.");
353                     }
354                 }
355             }
356             if(ee instanceof ExtensionException) {
357                 throw (ExtensionException)ee;
358             }
359             else {
360                 throw new ExtensionException(ExtensionException.INTERNAL_ERROR, ee);
361             }
362         }
363         launcherType.verifyRequiredElements();
364     }
365
366     private void addCat(PropertyDefinitionCategory cat, List JavaDoc<PropertyDefinitionCategory> l) {
367         l.add(cat);
368         for(PropertyDefinitionCategory c : cat.getCategories()) {
369             addCat(c, l);
370         }
371     }
372
373     void addCategories(PropertyClass propertyClass, Element el, PropertyDefinitionCategory parent) throws JDOMException {
374         PropertyDefinitionCategory cat = new DefaultPropertyDefinitionCategory(el.getAttribute("id").getIntValue(),
375             el.getAttributeValue("bundle"),
376             el.getAttributeValue("image"));
377         propertyClass.addPropertyDefinitionCategory(parent == null ? -1 : parent.getId(), cat);
378         for (Iterator JavaDoc i = el.getChildren().iterator(); i.hasNext();) {
379             addCategories(propertyClass, (Element) i.next(), cat);
380         }
381     }
382
383     public void activate() throws ExtensionException {
384         log.info("Activating extension descriptor " + getId());
385         launcherType.activate();
386     }
387
388     public void stop() throws ExtensionException {
389         log.info("Unloading extension descriptor " + getId());
390         unloadDefinitionsCategoriesAndMessages();
391         if (launcherType != null) {
392             launcherType.stop();
393         }
394     }
395
396     private void unloadDefinitionsCategoriesAndMessages() {
397         for (PropertyDefinition def : propertyDefinitions.values()) {
398             def.getPropertyClass().deregisterPropertyDefinition(def.getName());
399         }
400         for (PropertyDefinitionCategory cat : propertyDefinitionCategories.values()) {
401             cat.getPropertyClass().removePropertyDefinitionCategory(cat.getParent().getId(), cat);
402         }
403         for(String JavaDoc messageKey : messageKeys) {
404             messageResources.removeKey(messageKey);
405         }
406     }
407
408     public boolean canStop() {
409         try {
410             return launcherType != null ? launcherType.canStop() : true;
411         } catch (ExtensionException e) {
412             log.error("Failed to determine if extension may be stopped.", e);
413             return false;
414         }
415     }
416
417     public TunnelDescriptor getTunnel(String JavaDoc name) {
418         return (TunnelDescriptor) tunnels.get(name);
419     }
420
421     public ExtensionType getExtensionType() {
422         return launcherType;
423     }
424
425     private void addParameter(Element e) throws ExtensionException {
426         try {
427             ApplicationParameterDefinition definition = new ApplicationParameterDefinition(e);
428             parameters.put(definition.getName(), definition);
429         } catch (JDOMException jde) {
430             throw new ExtensionException(ExtensionException.FAILED_TO_PARSE_DESCRIPTOR, jde);
431         }
432     }
433
434     private void verifyTunnel(Element e) throws ExtensionException {
435         String JavaDoc name = e.getAttributeValue("name");
436         if (name == null || name.equals("")) {
437             throw new ExtensionException(ExtensionException.FAILED_TO_PROCESS_DESCRIPTOR,
438                 "name attribute required for <tunnel> element");
439         }
440         String JavaDoc hostname = e.getAttributeValue("hostname");
441         if (hostname == null || hostname.equals("")) {
442             throw new ExtensionException(ExtensionException.FAILED_TO_PROCESS_DESCRIPTOR,
443                 "hostname attribute required for <tunnel> element");
444         }
445         String JavaDoc port = e.getAttributeValue("port");
446         if (port == null || port.equals("")) {
447             throw new ExtensionException(ExtensionException.FAILED_TO_PROCESS_DESCRIPTOR,
448                 "port attribute required for <tunnel> element");
449         }
450         boolean usePreferredPort = !("false".equals(e.getAttributeValue("usePreferredPort")));
451         tunnels.put(name, new TunnelDescriptor(name, hostname, port, usePreferredPort));
452
453     }
454
455     public String JavaDoc getSmallIcon() {
456         return smallIcon;
457     }
458
459     public String JavaDoc getLargeIcon() {
460         return largeIcon;
461     }
462
463     public Set JavaDoc getParameters() {
464         return parameters.keySet();
465     }
466
467     public Map JavaDoc getParametersAndDefaults() {
468         return parameters;
469     }
470
471     public ApplicationParameterDefinition getParameterDefinition(String JavaDoc parameter) {
472         return (ApplicationParameterDefinition) parameters.get(parameter);
473     }
474
475     public static int[] getVersion(String JavaDoc version) {
476
477         int idx = 0;
478         int pos = 0;
479         int[] result = new int[0];
480         do {
481
482             idx = version.indexOf('.', pos);
483             int v;
484             if (idx > -1) {
485                 v = Integer.parseInt(version.substring(pos, idx));
486                 pos = idx + 1;
487             } else {
488                 int sub = version.indexOf('_', pos);
489                 if (sub > -1) {
490                     v = Integer.parseInt(version.substring(pos, sub));
491                 } else {
492                     v = Integer.parseInt(version.substring(pos));
493                 }
494             }
495             int[] tmp = new int[result.length + 1];
496             System.arraycopy(result, 0, tmp, 0, result.length);
497             tmp[tmp.length - 1] = v;
498             result = tmp;
499
500         } while (idx > -1);
501
502         return result;
503     }
504
505     private void verifyFiles(Element element) throws ExtensionException {
506
507         for (Iterator JavaDoc it = element.getChildren().iterator(); it.hasNext();) {
508             Element e = (Element) it.next();
509             if (e.getName().equalsIgnoreCase("if")) {
510                 verifyFiles(e);
511             } else if (!e.getName().equalsIgnoreCase("file")) {
512                 throw new ExtensionException(ExtensionException.FAILED_TO_PROCESS_DESCRIPTOR, "Unexpected element <" + e.getName()
513                     + "> found in <files>");
514             } else {
515                 processFile(e);
516             }
517         }
518
519     }
520
521     public Set JavaDoc getFiles() {
522         return files;
523     }
524
525     public void processFile(Element e) throws ExtensionException {
526
527         String JavaDoc filename = e.getAttributeValue("name");
528         if(filename == null || filename.equals("")) {
529              filename = e.getText();
530         }
531
532         File JavaDoc entry = getRealFile(filename);
533
534         if (!entry.exists()) {
535             if ("true".equals(System.getProperty("sslexplorer.useDevConfig", "false"))) {
536                 log.warn("File '" + filename + "' specified in extension descriptor " + bundle.getFile().getAbsolutePath()
537                     + " does not exist. As SSL-Explorer is running in Dev. mode, this will be ignored.");
538             } else {
539                 throw new ExtensionException(ExtensionException.FAILED_TO_PROCESS_DESCRIPTOR, "File '" + filename
540                     + "' specified in extension.xml does not exist! " + entry.getAbsolutePath());
541             }
542         } else {
543             try {
544                 e.setAttribute("checksum", String.valueOf(CoreUtil.generateChecksum(entry)));
545             } catch (IOException JavaDoc ioe) {
546                 throw new ExtensionException(ExtensionException.INTERNAL_ERROR, ioe, "Failed to generate checksum.");
547             }
548         }
549         e.setAttribute("size", String.valueOf(entry.length()));
550
551         files.add(filename);
552     }
553
554     public boolean containsFile(String JavaDoc filename) {
555         return files.contains(filename);
556     }
557
558     public File JavaDoc getFile(String JavaDoc filename) throws IOException JavaDoc {
559
560         if (!containsFile(filename)) {
561             throw new IOException JavaDoc(filename + " is not a valid application file");
562         }
563         return getRealFile(filename);
564     }
565     
566     File JavaDoc getRealFile(String JavaDoc filename) {
567         if("true".equals(System.getProperty("sslexplorer.useDevConfig"))) {
568             String JavaDoc basedir = ".." + File.separator + bundle.getId() + File.separator + "build" + File.separator + "extension";
569             if(filename == null) {
570                 return new File JavaDoc(basedir);
571             }
572             File JavaDoc realFile = new File JavaDoc(basedir, filename);
573             if(realFile.exists()) {
574                 return realFile;
575             }
576         }
577         String JavaDoc basedir = bundle.getFile().getParent();
578         if(filename == null) {
579             return new File JavaDoc(basedir);
580         }
581         return new File JavaDoc(basedir, filename);
582     }
583
584     /**
585      * @return
586      */

587     public CoreMessageResources getMessageResources() {
588         return messageResources;
589     }
590
591     public String JavaDoc getId() {
592         return id;
593     }
594
595     public String JavaDoc getName() {
596         return name;
597     }
598
599     public void setId(String JavaDoc id) {
600         this.id = id;
601     }
602
603     public void setName(String JavaDoc name) {
604         this.name = name;
605     }
606
607     public void setApplicationBundle(ExtensionBundle bundle) {
608         this.bundle = bundle;
609     }
610
611     public ExtensionBundle getApplicationBundle() {
612         return bundle;
613     }
614
615     public void removeDescriptor() {
616         // TODO 'uninstaller'
617
}
618
619     /**
620      * ARGGGGGGGGGGGGGGGGGGGGGGGGGGGHHHHHHHHHHHHHHHHHHHHHHHHH IF YOU
621      * ARE GOING TO ADD JAVADOC THEN MAKE IT USEFUL. NOT JUST ENOUGH
622      * TO GET RID OF THE COMPILER WARNINGS!!!!!!!!!!!!!!!!!!!!!
623      *
624      * @return
625      */

626     public Element createProcessedDescriptorElement(SessionInfo session) {
627         Element el = (Element) element.clone();
628         try {
629             launcherType.descriptorCreated(el, session);
630         } catch (IOException JavaDoc e) {
631             log.error("Failed to create processed descriptor element.", e);
632         }
633         return el;
634     }
635
636     public int compareTo(Object JavaDoc arg0) {
637         int c = bundle == null ? 0 : (bundle.getType() - ((ExtensionDescriptor) arg0).getApplicationBundle().getType());
638         return c != 0 ? c : name.compareTo(((ExtensionDescriptor) arg0).name);
639     }
640
641     public class TunnelDescriptor {
642         private String JavaDoc name;
643         private String JavaDoc hostname;
644         private String JavaDoc port;
645         private boolean usePreferredPort;
646
647         public TunnelDescriptor(String JavaDoc name, String JavaDoc hostname, String JavaDoc port, boolean usePreferredPort) {
648             this.name = name;
649             this.hostname = hostname;
650             this.port = port;
651             this.usePreferredPort = usePreferredPort;
652         }
653
654         public String JavaDoc getName() {
655             return name;
656         }
657
658         public String JavaDoc getHostname() {
659             return hostname;
660         }
661
662         public String JavaDoc getPort() {
663             return port;
664         }
665
666         public boolean isUsePreferredPort() {
667             return usePreferredPort;
668         }
669     }
670
671 }
672
Popular Tags