コード例 #1
0
ファイル: HostTest.java プロジェクト: applejian/cyberduck
 public void testParseWithTwoKlammeraffen() {
   {
     String url = "user@name@hostname";
     Host h = Host.parse(url);
     assertTrue(h.getHostname().equals("hostname"));
     assertTrue(
         h.getProtocol()
             .equals(
                 ProtocolFactory.forName(
                     Preferences.instance().getProperty("connection.protocol.default"))));
     assertNotNull(h.getCredentials().getUsername());
     assertTrue(h.getCredentials().getUsername().equals("user@name"));
     assertNull(h.getCredentials().getPassword());
   }
   {
     String url = "user@name:password@hostname";
     Host h = Host.parse(url);
     assertTrue(h.getHostname().equals("hostname"));
     assertTrue(
         h.getProtocol()
             .equals(
                 ProtocolFactory.forName(
                     Preferences.instance().getProperty("connection.protocol.default"))));
     assertNotNull(h.getCredentials().getUsername());
     assertTrue(h.getCredentials().getUsername().equals("user@name"));
     assertTrue(h.getCredentials().getPassword().equals("password"));
   }
 }
コード例 #2
0
ファイル: ImapProtocolImpl.java プロジェクト: atealxt/crm
  /**
   * @param msgId
   * @param destFolder
   * @throws Exception
   */
  public void moveEmail(Long msgId, String destFolder) throws Exception {
    ProtocolFactory factory = new ProtocolFactory(profile, auth, handler);
    ImapProtocolImpl fromProtocol = (ImapProtocolImpl) factory.getImap(folder);
    ImapProtocolImpl destProtocol = (ImapProtocolImpl) factory.getImap(destFolder);
    Folder from = fromProtocol.getFolder();
    Folder dest = null;

    try {
      Message msg = fromProtocol.getMessage(msgId.intValue());
      if (msg != null) {
        // because of the buggy imap servers lost the connection after getMessage
        // we need to check if the folder is open or not.
        // (Do not use uw-imapd, it sucks!!!)
        from = fromProtocol.getFolder();
        dest = destProtocol.getFolder();
        from.copyMessages(new Message[] {msg}, dest);
        // deleteMessages(new int[] {msg.getMessageNumber()});
        flagAsDeleted(new int[] {msg.getMessageNumber()});
      }
    } catch (IndexOutOfBoundsException e) {
      log.debug("Index kaçtı. Moving message to folder : " + destFolder + " failed.", e);
    } catch (Exception e) {
      log.warn("Moving message to folder : " + destFolder + " failed.", e);
    }
  }
コード例 #3
0
ファイル: HostTest.java プロジェクト: applejian/cyberduck
 public void testParseURLWithoutProtocol() {
   {
     String url = "user@hostname/path/to/file";
     Host h = Host.parse(url);
     assertTrue(h.getHostname().equals("hostname"));
     assertTrue(
         h.getProtocol()
             .equals(
                 ProtocolFactory.forName(
                     Preferences.instance().getProperty("connection.protocol.default"))));
     assertNotNull(h.getCredentials().getUsername());
     assertTrue(h.getCredentials().getUsername().equals("user"));
     assertNull(h.getCredentials().getPassword());
     assertTrue(h.getDefaultPath().equals("/path/to/file"));
   }
   {
     String url = "user@hostname";
     Host h = Host.parse(url);
     assertTrue(h.getHostname().equals("hostname"));
     assertTrue(
         h.getProtocol()
             .equals(
                 ProtocolFactory.forName(
                     Preferences.instance().getProperty("connection.protocol.default"))));
     assertNotNull(h.getCredentials().getUsername());
     assertTrue(h.getCredentials().getUsername().equals("user"));
     assertNull(h.getCredentials().getPassword());
   }
 }
コード例 #4
0
ファイル: ImapProtocolImpl.java プロジェクト: atealxt/crm
  /**
   * @param messageIds
   * @param destFolders
   * @throws Exception
   */
  public void moveEmails(int messageIds[], String destFolders[]) throws Exception {
    ProtocolFactory factory = new ProtocolFactory(profile, auth, handler);
    ImapProtocolImpl fromProtocol = (ImapProtocolImpl) factory.getImap(folder);
    Folder from = fromProtocol.getFolder();
    Folder dest = null;

    try {
      Message msg = null;
      // copy messages to destination folder first
      for (int i = 0; i < messageIds.length; i++) {
        try {
          msg = fromProtocol.getMessage(messageIds[i]);
          ImapProtocolImpl destProtocol = (ImapProtocolImpl) factory.getImap(destFolders[i]);
          dest = destProtocol.getFolder();
          from.copyMessages(new Message[] {msg}, dest);
        } catch (Exception e) {
          log.debug("error while copying messages", e);
        }
      }

      // now delete the processed messages all at a time.
      // deleteMessages(messageIds);
      flagAsDeleted(messageIds);

    } catch (Exception e) {
      log.warn("Moving message failed.", e);
    }
  }
コード例 #5
0
  /**
   * Parses protocol.
   *
   * @param xmlString protocol as XML string
   * @return protocol
   * @throws ProtocolException if error parsing protocol
   */
  public Protocol parseProtocol(String xmlString) {
    try {
      Document doc = DomUtil.makeDomFromString(xmlString, false);

      String protocolName = "";
      long flags = 0;
      List<String> vDest = null;
      StringAttributeMap properties = new StringAttributeMap();
      NodeList protocolNL = doc.getElementsByTagName("protocol");

      if (protocolNL.getLength() >= 1) {
        Node protocolN = protocolNL.item(0);

        NamedNodeMap attributes = protocolN.getAttributes();

        Node protocolTypeN = attributes.getNamedItem("type");
        protocolName = Val.chkStr(protocolTypeN != null ? protocolTypeN.getNodeValue() : "");

        Node flagsN = attributes.getNamedItem("flags");
        flags = flagsN != null ? Val.chkLong(Val.chkStr(flagsN.getNodeValue()), 0) : 0;

        Node destinationsN = attributes.getNamedItem("destinations");
        String sDest = destinationsN != null ? Val.chkStr(destinationsN.getNodeValue()) : null;
        vDest = sDest != null ? Arrays.asList(sDest.split(",")) : null;

        NodeList propertiesNL = protocolN.getChildNodes();
        for (int i = 0; i < propertiesNL.getLength(); i++) {
          Node property = propertiesNL.item(i);
          String propertyName = property.getNodeName();
          String propertyValue = property.getTextContent();
          properties.set(propertyName, propertyValue);
        }
      }

      ProtocolFactory protocolFactory = get(protocolName);
      if (protocolFactory == null) {
        throw new IllegalArgumentException("Unsupported protocol: " + protocolName);
      }

      Protocol protocol = protocolFactory.newProtocol();
      protocol.setFlags(flags);
      protocol.applyAttributeMap(properties);
      ProtocolInvoker.setDestinations(protocol, vDest);

      return protocol;
    } catch (ParserConfigurationException ex) {
      throw new IllegalArgumentException("Error parsing protocol.", ex);
    } catch (SAXException ex) {
      throw new IllegalArgumentException("Error parsing protocol.", ex);
    } catch (IOException ex) {
      throw new IllegalArgumentException("Error parsing protocol.", ex);
    }
  }
コード例 #6
0
  /**
   * @param args
   * @throws IOException
   */
  public static void main(String args[]) throws IOException {

    // Enable Debugging
    System.setProperty("DEBUG", "1");

    // Instantiate the Test Controller
    new TestDeviceManagerProtocol();

    // ********************************************
    // Prompt to enter a command
    // ********************************************

    System.out.println("Type exit to quit");
    System.out.print("SYSTEM>");

    BufferedReader keyboardInput;
    keyboardInput = new BufferedReader(new InputStreamReader(System.in));
    String command = "";

    try {
      while (!command.equalsIgnoreCase("exit")) {
        command = keyboardInput.readLine();
        if (!command.equalsIgnoreCase("exit")) {
          System.out.print("\nSYSTEM>");
        }
      }
    } finally {
      System.out.println("\nDisconnecting from ProtocolFactory");
      try {
        ProtocolFactory.shutdown();
      } catch (Exception e) {
      }
      ;
    }
  }
コード例 #7
0
ファイル: ImapProtocolImpl.java プロジェクト: atealxt/crm
  /** @return */
  public Folder[] listFolders() throws Exception {
    ProtocolFactory factory = new ProtocolFactory(profile, auth, handler);
    ImapProtocolImpl protocol = (ImapProtocolImpl) factory.getImap(folder);
    Folder f = protocol.getFolder();

    Folder parent = null;
    Folder[] folders = null;

    try {
      parent = f.getParent();
      folders = parent.listSubscribed("*");
    } catch (MessagingException e) {
      log.warn("Cannot get folder list.");
    } finally {
      // closeFolder(parent);
    }
    return folders;
  }
コード例 #8
0
ファイル: ImapProtocolImpl.java プロジェクト: atealxt/crm
  /**
   * @param buff
   * @throws Exception
   */
  public void appendEmail(byte[] buff) throws Exception {
    Properties props = new Properties();
    Session session = Session.getDefaultInstance(props);
    ByteArrayInputStream bis = new ByteArrayInputStream(buff);
    MimeMessage msg = new MimeMessage(session, bis);
    msg.setFlag(Flags.Flag.SEEN, true);

    ProtocolFactory factory = new ProtocolFactory(profile, auth, handler);
    ImapProtocolImpl imap = (ImapProtocolImpl) factory.getImap(folder);
    Folder f = imap.getFolder();

    try {
      f.appendMessages(new Message[] {msg});
    } catch (MessagingException e) {
      log.warn("appenging msg to folder : " + folder + " failed.", e);
    } finally {
      bis.close();
    }
  }
コード例 #9
0
ファイル: Host.java プロジェクト: kaduardo/cyberduck
 /**
  * @param protocol The protocol to use or null to use the default protocol for this port number
  */
 public void setProtocol(final Protocol protocol) {
   this.protocol =
       protocol != null
           ? protocol
           : ProtocolFactory.forName(
               Preferences.instance().getProperty("connection.protocol.default"));
   if (log.isDebugEnabled()) {
     log.debug(String.format("Set protocol bookmark %s to %s", this.getHostname(), this.protocol));
   }
   CredentialsConfiguratorFactory.get(this.protocol).configure(this.credentials, this.hostname);
 }
コード例 #10
0
ファイル: TestOOParser.java プロジェクト: Earne/HiBench
  public void testIt() throws ProtocolException, ParseException {
    String urlString;
    Content content;
    Parse parse;
    Configuration conf = NutchConfiguration.create();
    Protocol protocol;
    ProtocolFactory factory = new ProtocolFactory(conf);
    OOParser parser = new OOParser();
    parser.setConf(conf);

    for (int i = 0; i < sampleFiles.length; i++) {
      urlString = "file:" + sampleDir + fileSeparator + sampleFiles[i];

      protocol = factory.getProtocol(urlString);
      content = protocol.getProtocolOutput(new Text(urlString), new CrawlDatum()).getContent();

      parse = parser.getParse(content).get(content.getUrl());

      String text = parse.getText().replaceAll("[ \t\r\n]+", " ");
      assertTrue(expectedText.equals(text));
    }
  }
コード例 #11
0
ファイル: ImapProtocolImpl.java プロジェクト: atealxt/crm
  /**
   * @param messageIds
   * @param destFolder
   * @throws Exception
   */
  public void moveEmails(int messageIds[], String destFolder) throws Exception {
    ProtocolFactory factory = new ProtocolFactory(profile, auth, handler);
    ImapProtocolImpl fromProtocol = (ImapProtocolImpl) factory.getImap(folder);
    ImapProtocolImpl destProtocol = (ImapProtocolImpl) factory.getImap(destFolder);
    Folder from = fromProtocol.getFolder();
    Folder dest = null;

    try {
      Message msg = null;

      int counter = 0;
      dest = destProtocol.getFolder();
      Message msgs[] = new MimeMessage[messageIds.length];

      // copy messages to destination folder first
      for (int i = 0; i < messageIds.length; i++) {
        try {
          msg = fromProtocol.getMessage(messageIds[i]);

          if (msg != null) {
            msgs[counter] = msg;
            counter++;
          }
        } catch (Exception e) {
          log.debug("error while copying messages", e);
        }
      }

      from.copyMessages(msgs, dest);
      // now delete the processed messages all at a time.
      // deleteMessages(messageIds);
      flagAsDeleted(messageIds);
    } catch (IndexOutOfBoundsException e) {
      log.debug("Index kaçtı. Moving message to folder : " + destFolder + " failed.", e);
    } catch (Exception e) {
      log.warn("Moving message to folder : " + destFolder + " failed.", e);
    }
  }
コード例 #12
0
  public int run(String[] args) throws Exception {
    boolean dumpText = false;
    boolean force = false;
    String contentType = null;
    String url = null;

    String usage = "Usage: ParserChecker [-dumpText] [-forceAs mimeType] url";

    if (args.length == 0) {
      LOG.error(usage);
      return (-1);
    }

    for (int i = 0; i < args.length; i++) {
      if (args[i].equals("-forceAs")) {
        force = true;
        contentType = args[++i];
      } else if (args[i].equals("-dumpText")) {
        dumpText = true;
      } else if (i != args.length - 1) {
        LOG.error(usage);
        System.exit(-1);
      } else {
        url = URLUtil.toASCII(args[i]);
      }
    }

    if (LOG.isInfoEnabled()) {
      LOG.info("fetching: " + url);
    }

    ProtocolFactory factory = new ProtocolFactory(conf);
    Protocol protocol = factory.getProtocol(url);
    WebPage page = WebPage.newBuilder().build();

    ProtocolOutput protocolOutput = protocol.getProtocolOutput(url, page);

    if (!protocolOutput.getStatus().isSuccess()) {
      LOG.error(
          "Fetch failed with protocol status: "
              + ProtocolStatusUtils.getName(protocolOutput.getStatus().getCode())
              + ": "
              + ProtocolStatusUtils.getMessage(protocolOutput.getStatus()));
      return (-1);
    }
    Content content = protocolOutput.getContent();

    if (content == null) {
      LOG.error("No content for " + url);
      return (-1);
    }
    page.setBaseUrl(new org.apache.avro.util.Utf8(url));
    page.setContent(ByteBuffer.wrap(content.getContent()));

    if (force) {
      content.setContentType(contentType);
    } else {
      contentType = content.getContentType();
    }

    if (contentType == null) {
      LOG.error("Failed to determine content type!");
      return (-1);
    }

    page.setContentType(new Utf8(contentType));

    if (ParserJob.isTruncated(url, page)) {
      LOG.warn("Content is truncated, parse may fail!");
    }

    Parse parse = new ParseUtil(conf).parse(url, page);

    if (parse == null) {
      LOG.error("Problem with parse - check log");
      return (-1);
    }

    // Calculate the signature
    byte[] signature = SignatureFactory.getSignature(getConf()).calculate(page);

    if (LOG.isInfoEnabled()) {
      LOG.info("parsing: " + url);
      LOG.info("contentType: " + contentType);
      LOG.info("signature: " + StringUtil.toHexString(signature));
    }

    LOG.info("---------\nUrl\n---------------\n");
    System.out.print(url + "\n");
    LOG.info("---------\nMetadata\n---------\n");
    Map<CharSequence, ByteBuffer> metadata = page.getMetadata();
    StringBuffer sb = new StringBuffer();
    if (metadata != null) {
      Iterator<Entry<CharSequence, ByteBuffer>> iterator = metadata.entrySet().iterator();
      while (iterator.hasNext()) {
        Entry<CharSequence, ByteBuffer> entry = iterator.next();
        sb.append(entry.getKey().toString())
            .append(" : \t")
            .append(Bytes.toString(entry.getValue()))
            .append("\n");
      }
      System.out.print(sb.toString());
    }
    LOG.info("---------\nOutlinks\n---------\n");
    sb = new StringBuffer();
    for (Outlink l : parse.getOutlinks()) {
      sb.append("  outlink: ").append(l).append('\n');
    }
    System.out.print(sb.toString());
    if (page.getHeaders() != null) {
      LOG.info("---------\nHeaders\n---------\n");
      Map<CharSequence, CharSequence> headers = page.getHeaders();
      StringBuffer headersb = new StringBuffer();
      if (metadata != null) {
        Iterator<Entry<CharSequence, CharSequence>> iterator = headers.entrySet().iterator();
        while (iterator.hasNext()) {
          Entry<CharSequence, CharSequence> entry = iterator.next();
          headersb
              .append(entry.getKey().toString())
              .append(" : \t")
              .append(entry.getValue())
              .append("\n");
        }
        System.out.print(headersb.toString());
      }
    }
    if (dumpText) {
      LOG.info("---------\nParseText\n---------\n");
      System.out.print(parse.getText());
    }

    return 0;
  }
コード例 #13
0
ファイル: Host.java プロジェクト: kaduardo/cyberduck
 /**
  * Parses URL in the format ftp://username:pass@hostname:portnumber/path/to/file
  *
  * @param url URL
  * @return Bookmark
  */
 public static Host parse(final String url) {
   final String input = url.trim();
   int begin = 0;
   int cut;
   Protocol protocol = null;
   if (input.indexOf("://", begin) != -1) {
     cut = input.indexOf("://", begin);
     protocol = ProtocolFactory.forScheme(input.substring(begin, cut));
     if (null != protocol) {
       begin += cut - begin + 3;
     }
   }
   if (null == protocol) {
     protocol =
         ProtocolFactory.forName(
             Preferences.instance().getProperty("connection.protocol.default"));
   }
   String username;
   String password = null;
   if (protocol.isAnonymousConfigurable()) {
     username = Preferences.instance().getProperty("connection.login.anon.name");
   } else {
     username = Preferences.instance().getProperty("connection.login.name");
   }
   if (input.lastIndexOf('@') != -1) {
     if (input.indexOf(':', begin) != -1 && input.lastIndexOf('@') > input.indexOf(':', begin)) {
       // ':' is not for the port number but username:pass seperator
       cut = input.indexOf(':', begin);
       username = input.substring(begin, cut);
       begin += username.length() + 1;
       cut = input.lastIndexOf('@');
       password = input.substring(begin, cut);
       begin += password.length() + 1;
     } else {
       // no password given
       cut = input.lastIndexOf('@');
       username = input.substring(begin, cut);
       begin += username.length() + 1;
     }
   }
   String hostname = Preferences.instance().getProperty("connection.hostname.default");
   if (StringUtils.isNotBlank(input)) {
     hostname = input.substring(begin, input.length());
   }
   String path = null;
   int port = protocol.getDefaultPort();
   if (input.indexOf(':', begin) != -1) {
     cut = input.indexOf(':', begin);
     hostname = input.substring(begin, cut);
     begin += hostname.length() + 1;
     try {
       String portString;
       if (input.indexOf(Path.DELIMITER, begin) != -1) {
         portString = input.substring(begin, input.indexOf(Path.DELIMITER, begin));
         begin += portString.length();
         try {
           path = URLDecoder.decode(input.substring(begin, input.length()), "UTF-8");
         } catch (UnsupportedEncodingException e) {
           log.error(e.getMessage(), e);
         }
       } else {
         portString = input.substring(begin, input.length());
       }
       port = Integer.parseInt(portString);
     } catch (NumberFormatException e) {
       log.warn("Invalid port number given");
     }
   } else if (input.indexOf(Path.DELIMITER, begin) != -1) {
     cut = input.indexOf(Path.DELIMITER, begin);
     hostname = input.substring(begin, cut);
     begin += hostname.length();
     try {
       path = URLDecoder.decode(input.substring(begin, input.length()), "UTF-8");
     } catch (UnsupportedEncodingException e) {
       log.error(e.getMessage(), e);
     }
   }
   final Host h = new Host(protocol, hostname, port, path);
   h.setCredentials(username, password);
   return h;
 }
コード例 #14
0
ファイル: Host.java プロジェクト: kaduardo/cyberduck
 /** @param serialized A valid bookmark dictionary */
 public <T> Host(T serialized) {
   final Deserializer dict = DeserializerFactory.createDeserializer(serialized);
   Object uuidObj = dict.stringForKey("UUID");
   if (uuidObj != null) {
     this.setUuid(uuidObj.toString());
   }
   Object protocolObj = dict.stringForKey("Protocol");
   if (protocolObj != null) {
     this.setProtocol(ProtocolFactory.forName(protocolObj.toString()));
   }
   Object providerObj = dict.stringForKey("Provider");
   if (providerObj != null) {
     this.setProtocol(ProtocolFactory.forName(providerObj.toString()));
   }
   Object hostnameObj = dict.stringForKey("Hostname");
   if (hostnameObj != null) {
     this.setHostname(hostnameObj.toString());
   }
   Object usernameObj = dict.stringForKey("Username");
   if (usernameObj != null) {
     credentials.setUsername(usernameObj.toString());
   }
   Object passwordObj = dict.stringForKey("Password");
   if (passwordObj != null) {
     credentials.setPassword(passwordObj.toString());
   }
   Object cdnCredentialsObj = dict.stringForKey("CDN Credentials");
   if (cdnCredentialsObj != null) {
     cdnCredentials.setUsername(cdnCredentialsObj.toString());
   }
   Object keyObj = dict.stringForKey("Private Key File");
   if (keyObj != null) {
     this.getCredentials().setIdentity(LocalFactory.createLocal(keyObj.toString()));
   }
   Object portObj = dict.stringForKey("Port");
   if (portObj != null) {
     this.setPort(Integer.parseInt(portObj.toString()));
   }
   Object pathObj = dict.stringForKey("Path");
   if (pathObj != null) {
     this.setDefaultPath(pathObj.toString());
   }
   Object workdirObj = dict.stringForKey("Workdir");
   if (workdirObj != null) {
     this.setWorkdir(workdirObj.toString());
   }
   Object nicknameObj = dict.stringForKey("Nickname");
   if (nicknameObj != null) {
     this.setNickname(nicknameObj.toString());
   }
   Object encodingObj = dict.stringForKey("Encoding");
   if (encodingObj != null) {
     this.setEncoding(encodingObj.toString());
   }
   Object connectModeObj = dict.stringForKey("FTP Connect Mode");
   if (connectModeObj != null) {
     if (connectModeObj.toString().equals(FTPConnectMode.PORT.toString())) {
       this.setFTPConnectMode(FTPConnectMode.PORT);
     }
     if (connectModeObj.toString().equals(FTPConnectMode.PASV.toString())) {
       this.setFTPConnectMode(FTPConnectMode.PASV);
     }
   }
   Object connObj = dict.stringForKey("Maximum Connections");
   if (connObj != null) {
     this.setMaxConnections(Integer.valueOf(connObj.toString()));
   }
   Object downloadObj = dict.stringForKey("Download Folder");
   if (downloadObj != null) {
     this.setDownloadFolder(LocalFactory.createLocal(downloadObj.toString()));
   }
   Object timezoneObj = dict.stringForKey("Timezone");
   if (timezoneObj != null) {
     this.setTimezone(TimeZone.getTimeZone(timezoneObj.toString()));
   }
   Object commentObj = dict.stringForKey("Comment");
   if (commentObj != null) {
     this.setComment(commentObj.toString());
   }
   Object urlObj = dict.stringForKey("Web URL");
   if (urlObj != null) {
     this.setWebURL(urlObj.toString());
   }
   Object accessObj = dict.stringForKey("Access Timestamp");
   if (accessObj != null) {
     this.setTimestamp(new Date(Long.parseLong(accessObj.toString())));
   }
 }
コード例 #15
0
ファイル: Host.java プロジェクト: kaduardo/cyberduck
 /**
  * New host with the default protocol for this port
  *
  * @param hostname The hostname of the server
  * @param port The port number to connect to
  */
 public Host(String hostname, int port) {
   this(ProtocolFactory.getDefaultProtocol(port), hostname, port);
 }
コード例 #16
0
ファイル: Host.java プロジェクト: kaduardo/cyberduck
 /**
  * New host with the default protocol
  *
  * @param hostname The hostname of the server
  */
 public Host(String hostname) {
   this(
       ProtocolFactory.forName(Preferences.instance().getProperty("connection.protocol.default")),
       hostname);
 }
コード例 #17
0
  TestDeviceManagerProtocol() {

    // private member variables

    ProxyX10Appliance applianceProxy;
    ProxyX10MotionSensor motionSensorProxy;

    // fetch the EventGenerator
    eventGenerator = EventGeneratorFactory.getEventGenerator();
    eventGenerator.addEventListener(this);

    // initialize the ProtocolFactory
    System.out.println("Attempting to initialize the ProtocolFactory\n");
    try {
      ProtocolFactory.initProtocols();
    } catch (Exception e) {
      System.out.println("\nExiting program due to trouble initializing ProtocolFactory");
      System.exit(-1);
    }

    // Initialize the DeviceManager
    DeviceManager deviceManager = DeviceManagerFactory.getDeviceManager();

    // Instantiate the MotionSensor object
    motionSensorProxy = new ProxyX10MotionSensor("Motion C16", 'C', 16);
    motionSensorProxy.addAppliance("Appliance C1");
    motionSensorProxy.setDetectionPeriodEnabled(false);
    Calendar startTime = Calendar.getInstance();
    startTime.set(Calendar.HOUR_OF_DAY, 18);
    startTime.set(Calendar.MINUTE, 0);
    motionSensorProxy.setStartTime(startTime);
    Calendar endTime = Calendar.getInstance();
    endTime.set(Calendar.HOUR_OF_DAY, 19);
    endTime.set(Calendar.MINUTE, 0);
    motionSensorProxy.setEndTime(endTime);
    motionSensorProxy.setInactivityTimeEnabled(true);
    motionSensorProxy.setInactivityTime(10);
    deviceManager.addDevice(motionSensorProxy);

    // Instantiate the Appliance object
    applianceProxy = new ProxyX10Appliance("App C1", 'C', 1);
    applianceProxy.setTriggerTimerEnabled(false);
    deviceManager.addDevice(applianceProxy);

    try {
      Thread.sleep(3000);
    } catch (Exception e) {
    }

    System.out.println("Attempt to turn ON ApplianceProxy");
    applianceProxy.setState(X10DeviceState.ON);

    deviceManager.updateDevice(applianceProxy);

    try {
      Thread.sleep(3000);
    } catch (Exception e) {
    }

    System.out.println("Attempt to turn Off ApplianceProxy");
    applianceProxy.setState(X10DeviceState.OFF);
    deviceManager.updateDevice(applianceProxy);

    // Add more devices
    ProxyX10Appliance applianceProxy2 = new ProxyX10Appliance("Appliance C2", 'C', 2);
    applianceProxy2.setTriggerTimerEnabled(false);
    deviceManager.addDevice(applianceProxy2);

    ProxyX10Appliance applianceProxy3 = new ProxyX10Appliance("Appliance C3", 'C', 3);
    applianceProxy3.setTriggerTimerEnabled(false);
    deviceManager.addDevice(applianceProxy3);

    // Create an onTime
    Calendar onTime = Calendar.getInstance();
    onTime.set(Calendar.HOUR_OF_DAY, 10);
    onTime.set(Calendar.MINUTE, 12);
    onTime.set(Calendar.SECOND, 00);
    onTime.set(Calendar.MILLISECOND, 0);

    // Create an offTime
    Calendar offTime = Calendar.getInstance();
    offTime.set(Calendar.HOUR_OF_DAY, 12);
    offTime.set(Calendar.MINUTE, 13);
    offTime.set(Calendar.SECOND, 00);
    offTime.set(Calendar.MILLISECOND, 0);

    // Test creation of ProxyX10Appliance
    ProxyX10Appliance applianceProxy4 = new ProxyX10Appliance("Appliance A2", 'A', 2);
    applianceProxy4.setOnTime(onTime);
    applianceProxy4.setOffTime(offTime);
    applianceProxy4.setTriggerTimerEnabled(true);
    deviceManager.addDevice(applianceProxy4);
    applianceProxy4.setState(X10DeviceState.ON);
    deviceManager.updateDevice(applianceProxy4);

    try {
      Thread.sleep(3000);
    } catch (Exception e) {
    }

    applianceProxy4.setState(X10DeviceState.ON);
    deviceManager.updateDevice(applianceProxy4);

    // Test getDevices

    ArrayList<X10Device> deviceList = new ArrayList<X10Device>();
    System.out.println("Next Line should be INFO");
    deviceList = deviceManager.getDevices();

    int count = 1;
    for (X10Device device : deviceList) {
      System.out.println("Here are the contents of the Arraylist");
      System.out.println("Item " + count + " is named " + device.getName());
      count++;
    }
  }
コード例 #18
0
ファイル: Host.java プロジェクト: kaduardo/cyberduck
/** @version $Id: Host.java 10776 2013-03-23 16:19:21Z dkocher $ */
public final class Host implements Serializable {
  private static final Logger log = Logger.getLogger(Host.class);
  /**
   * The protocol identifier. Must be one of <code>sftp</code>, <code>ftp</code> or <code>ftps
   * </code>
   *
   * @see Protocol#FTP
   * @see Protocol#FTP_TLS
   * @see Protocol#SFTP
   */
  private Protocol protocol =
      ProtocolFactory.forName(Preferences.instance().getProperty("connection.protocol.default"));
  /**
   * The port number to connect to
   *
   * @see Protocol#getDefaultPort()
   */
  private int port = -1;
  /** The fully qualified hostname */
  private String hostname = Preferences.instance().getProperty("connection.hostname.default");

  /** The credentials to authenticate with */
  private Credentials credentials = new HostCredentials();

  /** The credentials to authenticate with for the CDN */
  private Credentials cdnCredentials = new CDNCredentials();

  /** Unique identifier */
  private String uuid;

  /** IDN normalized hostname */
  private String punycode;

  /** The given name by the user for the bookmark */
  private String nickname;

  /**
   * The initial working directory if any and absolute path to document root of webserver for Web
   * URL configuration
   */
  private String defaultpath;

  /** Current working directory when session was interrupted */
  private String workdir;

  /** The character encoding to use for file listings */
  private String encoding;

  /** The connect mode to use if FTP */
  private FTPConnectMode connectMode;

  /** The maximum number of concurrent sessions to this host */
  private Integer maxConnections;

  /** The custom download folder */
  private Local downloadFolder;

  /** The timezone the server is living in */
  private TimeZone timezone;

  /** Arbitrary text */
  private String comment;

  /** */
  private String webURL;

  /** Last accessed timestamp */
  private Date timestamp;

  /**
   * New host with the default protocol
   *
   * @param hostname The hostname of the server
   */
  public Host(String hostname) {
    this(
        ProtocolFactory.forName(Preferences.instance().getProperty("connection.protocol.default")),
        hostname);
  }

  /**
   * New host with the default protocol for this port
   *
   * @param hostname The hostname of the server
   * @param port The port number to connect to
   */
  public Host(String hostname, int port) {
    this(ProtocolFactory.getDefaultProtocol(port), hostname, port);
  }

  /**
   * @param protocol Scheme
   * @param hostname The hostname of the server
   */
  public Host(Protocol protocol, String hostname) {
    this(protocol, hostname, protocol.getDefaultPort());
  }

  /**
   * @param protocol Scheme
   * @param hostname The hostname of the server
   * @param credentials Login credentials
   */
  public Host(Protocol protocol, String hostname, Credentials credentials) {
    this(protocol, hostname, protocol.getDefaultPort());
    this.credentials = credentials;
  }

  /**
   * @param protocol The protocol to use, must be either Session.FTP or Session.SFTP
   * @param hostname The hostname of the server
   * @param port The port number to connect to
   */
  public Host(Protocol protocol, String hostname, int port) {
    this(protocol, hostname, port, null);
  }

  /**
   * @param protocol Scheme
   * @param hostname The hostname of the server
   * @param port Port number
   * @param defaultpath Default working directory
   */
  public Host(Protocol protocol, String hostname, int port, String defaultpath) {
    this.setProtocol(protocol);
    this.setPort(port);
    this.setHostname(hostname);
    this.setDefaultPath(defaultpath);
  }

  /** @param serialized A valid bookmark dictionary */
  public <T> Host(T serialized) {
    final Deserializer dict = DeserializerFactory.createDeserializer(serialized);
    Object uuidObj = dict.stringForKey("UUID");
    if (uuidObj != null) {
      this.setUuid(uuidObj.toString());
    }
    Object protocolObj = dict.stringForKey("Protocol");
    if (protocolObj != null) {
      this.setProtocol(ProtocolFactory.forName(protocolObj.toString()));
    }
    Object providerObj = dict.stringForKey("Provider");
    if (providerObj != null) {
      this.setProtocol(ProtocolFactory.forName(providerObj.toString()));
    }
    Object hostnameObj = dict.stringForKey("Hostname");
    if (hostnameObj != null) {
      this.setHostname(hostnameObj.toString());
    }
    Object usernameObj = dict.stringForKey("Username");
    if (usernameObj != null) {
      credentials.setUsername(usernameObj.toString());
    }
    Object passwordObj = dict.stringForKey("Password");
    if (passwordObj != null) {
      credentials.setPassword(passwordObj.toString());
    }
    Object cdnCredentialsObj = dict.stringForKey("CDN Credentials");
    if (cdnCredentialsObj != null) {
      cdnCredentials.setUsername(cdnCredentialsObj.toString());
    }
    Object keyObj = dict.stringForKey("Private Key File");
    if (keyObj != null) {
      this.getCredentials().setIdentity(LocalFactory.createLocal(keyObj.toString()));
    }
    Object portObj = dict.stringForKey("Port");
    if (portObj != null) {
      this.setPort(Integer.parseInt(portObj.toString()));
    }
    Object pathObj = dict.stringForKey("Path");
    if (pathObj != null) {
      this.setDefaultPath(pathObj.toString());
    }
    Object workdirObj = dict.stringForKey("Workdir");
    if (workdirObj != null) {
      this.setWorkdir(workdirObj.toString());
    }
    Object nicknameObj = dict.stringForKey("Nickname");
    if (nicknameObj != null) {
      this.setNickname(nicknameObj.toString());
    }
    Object encodingObj = dict.stringForKey("Encoding");
    if (encodingObj != null) {
      this.setEncoding(encodingObj.toString());
    }
    Object connectModeObj = dict.stringForKey("FTP Connect Mode");
    if (connectModeObj != null) {
      if (connectModeObj.toString().equals(FTPConnectMode.PORT.toString())) {
        this.setFTPConnectMode(FTPConnectMode.PORT);
      }
      if (connectModeObj.toString().equals(FTPConnectMode.PASV.toString())) {
        this.setFTPConnectMode(FTPConnectMode.PASV);
      }
    }
    Object connObj = dict.stringForKey("Maximum Connections");
    if (connObj != null) {
      this.setMaxConnections(Integer.valueOf(connObj.toString()));
    }
    Object downloadObj = dict.stringForKey("Download Folder");
    if (downloadObj != null) {
      this.setDownloadFolder(LocalFactory.createLocal(downloadObj.toString()));
    }
    Object timezoneObj = dict.stringForKey("Timezone");
    if (timezoneObj != null) {
      this.setTimezone(TimeZone.getTimeZone(timezoneObj.toString()));
    }
    Object commentObj = dict.stringForKey("Comment");
    if (commentObj != null) {
      this.setComment(commentObj.toString());
    }
    Object urlObj = dict.stringForKey("Web URL");
    if (urlObj != null) {
      this.setWebURL(urlObj.toString());
    }
    Object accessObj = dict.stringForKey("Access Timestamp");
    if (accessObj != null) {
      this.setTimestamp(new Date(Long.parseLong(accessObj.toString())));
    }
  }

  @Override
  public <T> T getAsDictionary() {
    final Serializer dict = SerializerFactory.createSerializer();
    dict.setStringForKey(this.getProtocol().getIdentifier(), "Protocol");
    if (StringUtils.isNotBlank(this.getProtocol().getProvider())) {
      if (!StringUtils.equals(
          this.getProtocol().getProvider(), this.getProtocol().getIdentifier())) {
        dict.setStringForKey(this.getProtocol().getProvider(), "Provider");
      }
    }
    dict.setStringForKey(this.getNickname(), "Nickname");
    dict.setStringForKey(this.getUuid(), "UUID");
    dict.setStringForKey(this.getHostname(), "Hostname");
    dict.setStringForKey(String.valueOf(this.getPort()), "Port");
    if (StringUtils.isNotBlank(this.getCredentials().getUsername())) {
      dict.setStringForKey(this.getCredentials().getUsername(), "Username");
    }
    if (StringUtils.isNotBlank(this.getCdnCredentials().getUsername())) {
      dict.setStringForKey(this.getCdnCredentials().getUsername(), "CDN Credentials");
    }
    if (StringUtils.isNotBlank(this.getDefaultPath())) {
      dict.setStringForKey(this.getDefaultPath(), "Path");
    }
    if (StringUtils.isNotBlank(this.getWorkdir())) {
      dict.setStringForKey(this.getWorkdir(), "Workdir");
    }
    if (StringUtils.isNotBlank(this.getEncoding())) {
      dict.setStringForKey(this.getEncoding(), "Encoding");
    }
    if (null != this.getCredentials().getIdentity()) {
      dict.setStringForKey(
          this.getCredentials().getIdentity().getAbbreviatedPath(), "Private Key File");
    }
    if (this.getProtocol().isConnectModeConfigurable()) {
      if (null != this.getFTPConnectMode()) {
        if (this.getFTPConnectMode().equals(FTPConnectMode.PORT)) {
          dict.setStringForKey(FTPConnectMode.PORT.toString(), "FTP Connect Mode");
        } else if (this.getFTPConnectMode().equals(FTPConnectMode.PASV)) {
          dict.setStringForKey(FTPConnectMode.PASV.toString(), "FTP Connect Mode");
        }
      }
    }
    if (null != this.getMaxConnections()) {
      dict.setStringForKey(String.valueOf(this.getMaxConnections()), "Maximum Connections");
    }
    if (!this.isDefaultDownloadFolder()) {
      dict.setStringForKey(this.getDownloadFolder().getAbbreviatedPath(), "Download Folder");
    }
    if (null != this.getTimezone()) {
      dict.setStringForKey(this.getTimezone().getID(), "Timezone");
    }
    if (StringUtils.isNotBlank(this.getComment())) {
      dict.setStringForKey(this.getComment(), "Comment");
    }
    if (!this.isDefaultWebURL()) {
      dict.setStringForKey(this.getWebURL(), "Web URL");
    }
    if (null != this.getTimestamp()) {
      dict.setStringForKey(String.valueOf(this.getTimestamp().getTime()), "Access Timestamp");
    }
    return dict.getSerialized();
  }

  /**
   * Parses URL in the format ftp://username:pass@hostname:portnumber/path/to/file
   *
   * @param url URL
   * @return Bookmark
   */
  public static Host parse(final String url) {
    final String input = url.trim();
    int begin = 0;
    int cut;
    Protocol protocol = null;
    if (input.indexOf("://", begin) != -1) {
      cut = input.indexOf("://", begin);
      protocol = ProtocolFactory.forScheme(input.substring(begin, cut));
      if (null != protocol) {
        begin += cut - begin + 3;
      }
    }
    if (null == protocol) {
      protocol =
          ProtocolFactory.forName(
              Preferences.instance().getProperty("connection.protocol.default"));
    }
    String username;
    String password = null;
    if (protocol.isAnonymousConfigurable()) {
      username = Preferences.instance().getProperty("connection.login.anon.name");
    } else {
      username = Preferences.instance().getProperty("connection.login.name");
    }
    if (input.lastIndexOf('@') != -1) {
      if (input.indexOf(':', begin) != -1 && input.lastIndexOf('@') > input.indexOf(':', begin)) {
        // ':' is not for the port number but username:pass seperator
        cut = input.indexOf(':', begin);
        username = input.substring(begin, cut);
        begin += username.length() + 1;
        cut = input.lastIndexOf('@');
        password = input.substring(begin, cut);
        begin += password.length() + 1;
      } else {
        // no password given
        cut = input.lastIndexOf('@');
        username = input.substring(begin, cut);
        begin += username.length() + 1;
      }
    }
    String hostname = Preferences.instance().getProperty("connection.hostname.default");
    if (StringUtils.isNotBlank(input)) {
      hostname = input.substring(begin, input.length());
    }
    String path = null;
    int port = protocol.getDefaultPort();
    if (input.indexOf(':', begin) != -1) {
      cut = input.indexOf(':', begin);
      hostname = input.substring(begin, cut);
      begin += hostname.length() + 1;
      try {
        String portString;
        if (input.indexOf(Path.DELIMITER, begin) != -1) {
          portString = input.substring(begin, input.indexOf(Path.DELIMITER, begin));
          begin += portString.length();
          try {
            path = URLDecoder.decode(input.substring(begin, input.length()), "UTF-8");
          } catch (UnsupportedEncodingException e) {
            log.error(e.getMessage(), e);
          }
        } else {
          portString = input.substring(begin, input.length());
        }
        port = Integer.parseInt(portString);
      } catch (NumberFormatException e) {
        log.warn("Invalid port number given");
      }
    } else if (input.indexOf(Path.DELIMITER, begin) != -1) {
      cut = input.indexOf(Path.DELIMITER, begin);
      hostname = input.substring(begin, cut);
      begin += hostname.length();
      try {
        path = URLDecoder.decode(input.substring(begin, input.length()), "UTF-8");
      } catch (UnsupportedEncodingException e) {
        log.error(e.getMessage(), e);
      }
    }
    final Host h = new Host(protocol, hostname, port, path);
    h.setCredentials(username, password);
    return h;
  }

  // ----------------------------------------------------------

  /** @param defaultpath The path to change the working directory to upon connecting */
  public void setDefaultPath(String defaultpath) {
    this.defaultpath =
        StringUtils.isBlank(defaultpath)
            ? null
            : StringUtils.remove(StringUtils.remove(defaultpath, CharUtils.LF), CharUtils.CR)
                .trim();
  }

  /** @return Null if no default path is set */
  public String getDefaultPath() {
    return this.defaultpath;
  }

  public String getWorkdir() {
    return workdir;
  }

  public void setWorkdir(String workdir) {
    this.workdir = workdir;
  }

  /**
   * @param username User
   * @param password Secret
   */
  public void setCredentials(final String username, final String password) {
    credentials.setUsername(username);
    credentials.setPassword(password);
  }

  public void setCredentials(Credentials credentials) {
    this.credentials = credentials;
  }

  public Credentials getCredentials() {
    return credentials;
  }

  /** @return Credentials to modify CDN configuration */
  public Credentials getCdnCredentials() {
    return cdnCredentials;
  }

  /**
   * @param protocol The protocol to use or null to use the default protocol for this port number
   */
  public void setProtocol(final Protocol protocol) {
    this.protocol =
        protocol != null
            ? protocol
            : ProtocolFactory.forName(
                Preferences.instance().getProperty("connection.protocol.default"));
    if (log.isDebugEnabled()) {
      log.debug(String.format("Set protocol bookmark %s to %s", this.getHostname(), this.protocol));
    }
    CredentialsConfiguratorFactory.get(this.protocol).configure(this.credentials, this.hostname);
  }

  /**
   * @return Scheme
   * @see Protocol#FTP
   * @see Protocol#FTP_TLS
   * @see Protocol#SFTP
   */
  public Protocol getProtocol() {
    return this.protocol;
  }

  public String getUuid() {
    if (null == uuid) {
      uuid = UUID.randomUUID().toString();
    }
    return uuid;
  }

  public void setUuid(String uuid) {
    this.uuid = uuid;
  }

  /**
   * The given name for this bookmark
   *
   * @return The user-given name of this bookmark
   */
  public String getNickname() {
    return this.getNickname(false);
  }

  public String getNickname(boolean escape) {
    if (StringUtils.isEmpty(nickname)) {
      return this.getDefaultNickname();
    }
    if (escape) {
      return StringUtils.replace(nickname, "/", ":");
    }
    return nickname;
  }

  /** @return The default given name of this bookmark */
  private String getDefaultNickname() {
    if (StringUtils.isNotEmpty(this.getHostname())) {
      return this.getHostname() + " \u2013 " + this.getProtocol().getName();
    }
    return StringUtils.EMPTY;
  }

  /**
   * Sets a user-given name for this bookmark
   *
   * @param nickname Custom name
   */
  public void setNickname(String nickname) {
    if (this.getDefaultNickname().equals(nickname)) {
      return;
    }
    this.nickname = nickname;
  }

  /** @return User readable hostname */
  public String getHostname() {
    return this.getHostname(false);
  }

  /**
   * @param punycode Use the ToASCII operation as defined in the IDNA RFC
   * @return Hostname decoded
   */
  public String getHostname(boolean punycode) {
    if (punycode && Preferences.instance().getBoolean("connection.hostname.idn")) {
      if (null == this.punycode && StringUtils.isNotEmpty(hostname)) {
        try {
          // Convenience function that implements the IDNToASCII operation as defined in
          // the IDNA RFC. This operation is done on complete domain names, e.g: "www.example.com".
          // It is important to note that this operation can fail. If it fails, then the input
          // domain name cannot be used as an Internationalized Domain Name and the application
          // should have methods defined to deal with the failure.
          // IDNA.DEFAULT Use default options, i.e., do not process unassigned code points
          // and do not use STD3 ASCII rules If unassigned code points are found
          // the operation fails with ParseException
          final String idn = IDNA.convertIDNToASCII(hostname, IDNA.DEFAULT).toString();
          if (log.isInfoEnabled()) {
            log.info(String.format("IDN hostname for %s is %s", hostname, idn));
          }
          this.punycode = idn;
        } catch (StringPrepParseException e) {
          log.error(String.format("Failed to convert hostname %s to IDNA", hostname), e);
        }
      }
      if (StringUtils.isNotEmpty(this.punycode)) {
        return this.punycode;
      }
    }
    return this.hostname;
  }

  /**
   * Sets the name for this host. Also reverts the nickname if no custom nickname is set.
   *
   * <p>Configures credentials according to new hostname.
   *
   * @param hostname Server
   */
  public void setHostname(final String hostname) {
    if (this.protocol.isHostnameConfigurable()) {
      this.hostname = hostname.trim();
    } else {
      this.hostname = protocol.getDefaultHostname();
    }
    this.punycode = null;
    CredentialsConfiguratorFactory.get(this.protocol).configure(this.credentials, this.hostname);
  }

  /** @param port The port number to connect to or -1 to use the default port for this protocol */
  public void setPort(final int port) {
    this.port = port;
    if (-1 == port) {
      this.port = this.protocol.getDefaultPort();
    }
  }

  /** @return The port number a socket should be opened to */
  public int getPort() {
    return this.port;
  }

  /**
   * The character encoding to be used with this host
   *
   * @param encoding Control connection encoding
   */
  public void setEncoding(final String encoding) {
    this.encoding = encoding;
  }

  /**
   * @return The character encoding to be used when connecting to this server or null if the default
   *     encoding should be used
   */
  public String getEncoding() {
    return encoding;
  }

  public void setFTPConnectMode(final FTPConnectMode connectMode) {
    this.connectMode = connectMode;
  }

  /**
   * @return The connect mode to be used when connecting to this server or null if the default
   *     connect mode should be used
   */
  public FTPConnectMode getFTPConnectMode() {
    return connectMode;
  }

  /**
   * Set a custom number of concurrent sessions allowed for this host If not set,
   * connection.pool.max is used.
   *
   * @param n null to use the default value or -1 if no limit
   */
  public void setMaxConnections(final Integer n) {
    this.maxConnections = n;
  }

  /**
   * @return The number of concurrent sessions allowed. -1 if unlimited or null if the default
   *     should be used
   */
  public Integer getMaxConnections() {
    return maxConnections;
  }

  /**
   * Set a custom download folder instead of queue.download.folder
   *
   * @param folder Absolute path
   */
  public void setDownloadFolder(final Local folder) {
    if (log.isDebugEnabled()) {
      log.debug(
          String.format("Set download folder for bookmark %s to %s", this.getHostname(), folder));
    }
    downloadFolder = folder;
  }

  /**
   * The custom folder if any or the default download location
   *
   * @return Absolute path
   */
  public Local getDownloadFolder() {
    if (null == downloadFolder) {
      return LocalFactory.createLocal(Preferences.instance().getProperty("queue.download.folder"));
    }
    return downloadFolder;
  }

  /** @return True if no custom download location is set */
  public boolean isDefaultDownloadFolder() {
    return null == downloadFolder;
  }

  /**
   * Set a timezone for the remote server different from the local default timezone May be useful to
   * display modification dates of remote files correctly using the local timezone
   *
   * @param timezone Timezone of server
   */
  public void setTimezone(final TimeZone timezone) {
    this.timezone = timezone;
  }

  /** @return The custom timezone or null if not set */
  public TimeZone getTimezone() {
    return this.timezone;
  }

  /** @param comment Notice */
  public void setComment(final String comment) {
    this.comment = comment;
  }

  /** @return Notice */
  public String getComment() {
    return this.comment;
  }

  /** @return HTTP accessible URL */
  public String getWebURL() {
    if (StringUtils.isBlank(webURL)) {
      return this.getDefaultWebURL();
    }
    final String regex = "^http(s)?://.*$";
    if (!webURL.matches(regex)) {
      webURL = "http://" + webURL;
    }
    return webURL;
  }

  /** @return True if no custom web URL has been set */
  public boolean isDefaultWebURL() {
    return this.getWebURL().equals(this.getDefaultWebURL());
  }

  /** @return HTTP accessible URL with the same hostname as the server */
  public String getDefaultWebURL() {
    return "http://" + this.getHostname();
  }

  public void setWebURL(final String url) {
    if (this.getDefaultWebURL().equals(url)) {
      webURL = null;
      return;
    }
    webURL = url;
  }

  /** @return The date this bookmark was last accessed. */
  public Date getTimestamp() {
    return timestamp;
  }

  /**
   * Update the time this bookmark was last accessed.
   *
   * @param timestamp Date and time
   */
  public void setTimestamp(Date timestamp) {
    this.timestamp = timestamp;
  }

  /**
   * @return The URL of the remote host including user login hostname and port
   * @see #toURL()
   */
  @Override
  public String toString() {
    return this.toURL();
  }

  /**
   * protocol://user@host:port
   *
   * @return The URL of the remote host including user login hostname and port
   * @see #toURL(boolean)
   */
  public String toURL() {
    return this.toURL(true);
  }

  /**
   * @param includeUsername Prepend username to host
   * @return URL
   */
  public String toURL(final boolean includeUsername) {
    StringBuilder url = new StringBuilder(this.getProtocol().getScheme().toString());
    url.append("://");
    if (includeUsername && StringUtils.isNotEmpty(this.getCredentials().getUsername())) {
      url.append(this.getCredentials().getUsername()).append("@");
    }
    url.append(this.getHostname(true));
    if (this.getPort() != this.getProtocol().getScheme().getPort()) {
      url.append(":").append(this.getPort());
    }
    return url.toString();
  }

  @Override
  public boolean equals(Object other) {
    if (null == other) {
      return false;
    }
    if (other instanceof Host) {
      return this.getUuid().equals(((Host) other).getUuid());
    }
    return false;
  }

  @Override
  public int hashCode() {
    return this.getUuid().hashCode();
  }

  private static final class CDNCredentials extends Credentials {
    @Override
    public String getUsernamePlaceholder() {
      return Locale.localizedString("Access Key ID", "S3");
    }

    @Override
    public String getPasswordPlaceholder() {
      return Locale.localizedString("Secret Access Key", "S3");
    }
  }

  private final class HostCredentials extends Credentials {

    public HostCredentials() {
      super(Preferences.instance().getProperty("connection.login.name"), null);
    }

    @Override
    public String getUsernamePlaceholder() {
      return getProtocol().getUsernamePlaceholder();
    }

    @Override
    public String getPasswordPlaceholder() {
      return getProtocol().getPasswordPlaceholder();
    }
  }
}