/**
   * Returns true if the code was executed correctly. False if there was an error trying to share
   * the file. If the file was not supposed to be shared, and was not shared, true would still be
   * returned.
   */
  private boolean shareTorrentFile(File torrentFile) {
    if (torrentManager.isDownloadingTorrent(torrentFile)) {
      return true;
    }

    if (!SharingSettings.SHARE_DOWNLOADED_FILES_IN_NON_SHARED_DIRECTORIES.getValue()) {
      return true;
    }

    BTData btData = null;
    FileInputStream torrentInputStream = null;
    try {
      torrentInputStream = new FileInputStream(torrentFile);
      Map<?, ?> torrentFileMap = (Map<?, ?>) Token.parse(torrentInputStream.getChannel());
      btData = new BTDataImpl(torrentFileMap);
    } catch (IOException e) {
      LOG.error("Error reading torrent file: " + torrentFile, e);
      return false;
    } finally {
      FileUtils.close(torrentInputStream);
    }

    if (btData.isPrivate()) {
      gnutellaFileList.remove(torrentFile);
      return true;
    }

    File saveDir = SharingSettings.getSaveDirectory();
    File torrentParent = torrentFile.getParentFile();
    if (torrentParent.equals(saveDir)) {
      // already in saveDir
      gnutellaFileList.add(torrentFile);
      return true;
    }

    final File tFile = getSharedTorrentMetaDataFile(btData);
    if (tFile.equals(torrentFile)) {
      gnutellaFileList.add(tFile);
      return true;
    }

    gnutellaFileList.remove(tFile);
    File backup = null;
    if (tFile.exists()) {
      backup = new File(tFile.getParent(), tFile.getName().concat(".bak"));
      FileUtils.forceRename(tFile, backup);
    }

    if (FileUtils.copy(torrentFile, tFile)) {
      gnutellaFileList.add(tFile);
    } else {
      if (backup != null) {
        // restore backup
        if (FileUtils.forceRename(backup, tFile)) {
          gnutellaFileList.add(tFile);
        }
      }
    }
    return true;
  }
 void loginImpl() throws FriendException {
   synchronized (this) {
     try {
       loggingIn.set(true);
       connectionMulticaster.broadcast(
           new FriendConnectionEvent(this, FriendConnectionEvent.Type.CONNECTING));
       org.jivesoftware.smack.XMPPConnection.addConnectionCreationListener(
           smackConnectionListener);
       org.jivesoftware.smack.XMPPConnection.DEBUG_ENABLED = configuration.isDebugEnabled();
       connect();
       LOG.infof("connected.");
       LOG.infof(
           "logging in {0} with resource: {1} ...",
           configuration.getUserInputLocalID(), configuration.getResource());
       connection.login(
           configuration.getUserInputLocalID(),
           configuration.getPassword(),
           configuration.getResource());
       LOG.infof("logged in.");
       loggedIn.set(true);
       loggingIn.set(false);
       connectionMulticaster.broadcast(
           new FriendConnectionEvent(this, FriendConnectionEvent.Type.CONNECTED));
     } catch (org.jivesoftware.smack.XMPPException e) {
       handleLoginError(e);
       throw new FriendException(e);
     } catch (RuntimeException e) {
       handleLoginError(e);
       throw e;
     }
   }
 }
 /** @param error null if connection is closed by user */
 void logoutImpl(Exception error) {
   synchronized (this) {
     if (isLoggedIn()) {
       loggedIn.set(false);
       LOG.infof(
           "disconnecting from {0} at {1}:{2} ...",
           connection.getServiceName(), connection.getHost(), connection.getPort());
       connection.disconnect();
       synchronized (friends) {
         friends.clear();
       }
       XMPPConnection.removeConnectionCreationListener(smackConnectionListener);
       connection = null;
       LOG.info("disconnected.");
       connectionMulticaster.broadcast(
           new FriendConnectionEvent(
               XMPPFriendConnectionImpl.this, FriendConnectionEvent.Type.DISCONNECTED, error));
       ChatStateManager.remove(connection);
       if (discoInfoListener != null) {
         discoInfoListener.cleanup();
       }
       if (noSaveFeatureInitializer != null) {
         noSaveFeatureInitializer.cleanup();
       }
       if (idleStatusMonitor != null) {
         idleStatusMonitor.stop();
       }
       if (xmppActivityListener != null) {
         xmppActivitySupport.removeListener(xmppActivityListener);
       }
       featureRegistry.deregisterInitializer(NoSaveFeature.ID);
     }
   }
 }
 /**
  * Called to indicate a new chat state in this conversation.
  *
  * @param chatState being added.
  */
 public void newChatState(ChatState chatState) {
   LOG.debugf("Chat state update for {0} to {1}", chatFriend.getName(), chatState);
   if (currentChatState != chatState) {
     currentChatState = chatState;
     displayMessages();
   }
 }
  /**
   * Registers a new channel with this Selector. If we've already stored over the limit of channels,
   * this will store the channel in a temporary list to be cancelled on the next selection.
   */
  @Override
  protected synchronized SelectionKey register(AbstractSelectableChannel ch, int ops, Object att) {
    int connID;

    if (!(ch instanceof UDPSocketChannel)) throw new IllegalSelectorException();

    UDPSocketChannel channel = (UDPSocketChannel) ch;

    UDPSocketChannel[] copy = new UDPSocketChannel[_channels.length];
    for (int i = 0; i < _channels.length; i++) copy[i] = _channels[i];

    for (int i = 1; i <= copy.length; i++) {
      connID = (_lastConnectionID + i) % 256;

      // We don't assign zero.
      if (connID == 0) continue;

      // If the slot is open, take it.
      if (copy[connID] == null) {
        _lastConnectionID = connID;
        copy[connID] = channel;
        channel.getProcessor().setConnectionId((byte) connID);
        _channels = copy;
        return new UDPSelectionKey(this, att, ch, ops);
      }
    }

    // We don't have enough space for this connection.  Add it to a temporary
    // list of bad connections which will be removed during selectNow.
    LOG.warn("Attempting to add over connection limit");
    channelsToRemove.add(ch);
    return new UDPSelectionKey(this, att, ch, ops);
  }
 public void sendFeature(FriendPresence presence, Address address) throws FriendException {
   LOG.debugf("sending new address to {0}", presence);
   AddressIQ queryResult = new AddressIQ(address, factory);
   queryResult.setTo(presence.getPresenceId());
   queryResult.setFrom(connection.getLocalJid());
   queryResult.setType(IQ.Type.SET);
   connection.sendPacket(queryResult);
 }
 private void connect() throws org.jivesoftware.smack.XMPPException {
   for (ConnectionConfigurationFactory factory : connectionConfigurationFactories) {
     try {
       connectUsingFactory(factory);
       return;
     } catch (FriendException e) {
       LOG.debug(e.getMessage(), e);
     }
   }
 }
 /** Notification that meta information has changed in the filedesc. */
 protected void updateFileDesc(FileDesc fd) {
   LocalFileItem item = (LocalFileItem) fd.getClientProperty(FILE_ITEM_PROPERTY);
   if (item != null) {
     threadSafeList.getReadWriteLock().writeLock().lock();
     try {
       int idx = threadSafeList.indexOf(item);
       if (idx > 0) {
         threadSafeList.set(idx, item);
       } else {
         LOG.warnf(
             "Attempted to update FD w/ LocalFileItem that is not in list anymore. Item {0}",
             item);
       }
     } finally {
       threadSafeList.getReadWriteLock().writeLock().unlock();
     }
   } else {
     LOG.warnf("Attempted to update FD without LocalFileItem, FD {0}", fd);
   }
 }
  /** Adds the specified search result to the results list. */
  @Override
  public void addSearchResult(SearchResult result) {
    if (result.getUrn() == null) {
      // Some results can be missing a URN, specifically
      // secure results.  For now, we drop these.
      // We should figure out a way to show them later on.
      return;
    }

    LOG.debugf("Adding result urn: {0} EDT: {1}", result.getUrn(), EventQueue.isDispatchThread());
    allSearchResults.add(result);
  }
  private void handleLinkClick(String linkDescription, URL url) {

    if (ChatDocumentBuilder.LIBRARY_LINK.equals(linkDescription)) {
      ChatFriend libraryChatFriend = conversation.getChatFriend();
      LOG.debugf("Opening a view to {0}'s library", libraryChatFriend.getName());
      //            libraryNavigator.selectFriendLibrary(libraryChatFriend.getFriend());
      throw new IllegalStateException("action does't exist");

    } else if (ChatDocumentBuilder.MY_LIBRARY_LINK.equals(linkDescription)) {
      LOG.debugf("Opening a view to my library");
      //            libraryNavigator.selectLibrary();
      throw new IllegalStateException("action does't exist");
    } else {
      LOG.debugf("Hyperlink clicked: {0}", linkDescription);
      if (linkDescription.startsWith("magnet")) {
        // TODO: Need to do something with magnet links

      } else if (url != null) {
        NativeLaunchUtils.openURL(url.toString());
      }
    }
  }
 private void connectUsingFactory(ConnectionConfigurationFactory factory) throws FriendException {
   ConnectionConfigurationFactory.RequestContext requestContext =
       new ConnectionConfigurationFactory.RequestContext();
   while (factory.hasMore(configuration, requestContext)) {
     ConnectionConfiguration connectionConfig =
         factory.getConnectionConfiguration(configuration, requestContext);
     connection = new XMPPConnection(connectionConfig);
     connection.addRosterListener(new RosterListenerImpl());
     LOG.infof(
         "connecting to {0} at {1}:{2} ...",
         connectionConfig.getServiceName(),
         connectionConfig.getHost(),
         connectionConfig.getPort());
     try {
       connection.connect();
       return;
     } catch (org.jivesoftware.smack.XMPPException e) {
       LOG.debug(e.getMessage(), e);
       requestContext.incrementRequests();
     }
   }
   throw new FriendException("couldn't connect using " + factory);
 }
Exemple #12
0
  /**
   * Route a message to the {@link UDPConnectionProcessor} identified via the message's connection
   * ID. Notifies the provided listener (if any) if the channel is ready to produce events.
   */
  public void routeMessage(RUDPMessage msg, InetSocketAddress addr) {
    UDPSocketChannel[] array = _channels;
    int connID = msg.getConnectionID() & 0xff;
    UDPSocketChannel channel = null;
    // If connID equals 0 and SynMessage then associate with a connection
    // that appears to want it (connecting and with knowledge of it).
    if (connID == 0 && msg instanceof SynMessage) {
      LOG.debugf("route sym: {0}", msg);
      for (int i = 1; i < array.length; i++) {
        channel = array[i];
        if (channel == null) continue;

        LOG.debugf("non-empty index: {0}, addr: {1}", i, channel.getRemoteSocketAddress());

        if (channel.isConnectionPending() && channel.isForMe(addr, (SynMessage) msg)) {
          LOG.debugf(
              "found index: {0}, sender id: {1}", i, ((SynMessage) msg).getSenderConnectionID());
          channel.getProcessor().handleMessage(msg);
          break;
        }
      }
      // Note: eventually these messages should find a match
      // so it is safe to throw away premature ones

    } else if (array[connID] != null) { // If valid connID then send on to connection
      channel = array[connID];
      if (msg instanceof SynMessage) {
        LOG.debugf("already assigned syn: {0}", msg);
      }
      if (channel.getRemoteSocketAddress().equals(addr)) channel.getProcessor().handleMessage(msg);
    } else {
      LOG.debugf("message for non-existing connection: {0}", msg);
    }

    if (channel != null && channel.getProcessor().readyOps() != 0)
      context.getTransportListener().eventPending();
  }
  /**
   * Download the file offer given a file ID.
   *
   * <p>package-private for testing
   *
   * @param fileId identifier to look up the file offer message
   */
  void downloadFileOffer(String fileId) {
    Map<String, MessageFileOffer> fileOffers = conversation.getFileOfferMessages();
    MessageFileOffer msgWithfileOffer = fileOffers.get(fileId);
    SearchResult file = null;

    try {
      file =
          remoteFileItemFactory.create(
              msgWithfileOffer.getPresence(), msgWithfileOffer.getFileOffer());
      DownloadItem dl = downloader.addDownload(null, Collections.singletonList(file));

      // Track download states by adding listeners to dl item
      addPropertyListener(dl, msgWithfileOffer);

    } catch (DownloadException e) {
      final SearchResult remoteFileItem = file;
      final MessageFileOffer messageFileOffer = msgWithfileOffer;
      downloadExceptionHandler
          .get()
          .handleDownloadException(
              new DownloadAction() {
                @Override
                public void download(File saveFile, boolean overwrite) throws DownloadException {
                  DownloadItem dl =
                      downloader.addDownload(
                          null, Collections.singletonList(remoteFileItem), saveFile, overwrite);
                  addPropertyListener(dl, messageFileOffer);
                }

                @Override
                public void downloadCanceled(DownloadException ignored) {
                  // nothing to do
                }
              },
              e,
              true);
    } catch (InvalidDataException ide) {
      // this means the FileMetaData we received isn't well-formed.
      LOG.error("Unable to access remote file", ide);
      FocusJOptionPane.showMessageDialog(
          null,
          I18n.tr("Unable to access remote file"),
          I18n.tr("Hyperlink"),
          JOptionPane.WARNING_MESSAGE);
    }
  }
  /** Initiates a download of the specified visual search result to the specified save file. */
  @Override
  public void download(final VisualSearchResult vsr, File saveFile) {
    try {
      // Add download to manager.  If save file is specified, then set
      // overwrite to true because the user has already confirmed it.
      DownloadItem di =
          (saveFile == null)
              ? downloadListManager.addDownload(search, vsr.getCoreSearchResults())
              : downloadListManager.addDownload(search, vsr.getCoreSearchResults(), saveFile, true);

      // Add listener, and initialize download state.
      di.addPropertyChangeListener(new DownloadItemPropertyListener(vsr));
      vsr.setDownloadState(BasicDownloadState.DOWNLOADING);

    } catch (final SaveLocationException sle) {
      if (sle.getErrorCode() == SaveLocationException.LocationCode.FILE_ALREADY_DOWNLOADING) {
        DownloadItem downloadItem = downloadListManager.getDownloadItem(vsr.getUrn());
        if (downloadItem != null) {
          downloadItem.addPropertyChangeListener(new DownloadItemPropertyListener(vsr));
          vsr.setDownloadState(BasicDownloadState.DOWNLOADING);
          if (saveFile != null) {
            try {
              // Update save file in DownloadItem.
              downloadItem.setSaveFile(saveFile, true);
            } catch (SaveLocationException ex) {
              LOG.infof(ex, "Unable to relocate downloading file {0}", ex.getMessage());
            }
          }
        }
      } else {
        saveLocationExceptionHandler.handleSaveLocationException(
            new DownloadAction() {
              @Override
              public void download(File saveFile, boolean overwrite) throws SaveLocationException {
                DownloadItem di =
                    downloadListManager.addDownload(
                        search, vsr.getCoreSearchResults(), saveFile, overwrite);
                di.addPropertyChangeListener(new DownloadItemPropertyListener(vsr));
                vsr.setDownloadState(BasicDownloadState.DOWNLOADING);
              }
            },
            sle,
            true);
      }
    }
  }
  /**
   * Add a new {@link Message} to this conversation.
   *
   * @param message being added
   */
  public void newChatMessage(Message message) {
    // TODO: Refactor this,ChatDocumentBuilder, etc into cleaner/clearer, way to display msgs
    LOG.debugf("Message: from {0} text: {1}", message.getSenderName(), message.toString());
    messages.add(message);
    Type type = message.getType();

    if (type != Type.SENT) {
      currentChatState = ChatState.active;
    }

    if (message instanceof MessageFileOffer) {
      MessageFileOffer msgWithFileOffer = (MessageFileOffer) message;
      addFileOfferMessage(msgWithFileOffer);
    } else if (message instanceof NoSaveStatusMessage) {
      updateNoSaveLink(((NoSaveStatusMessage) message).getStatus());
    }

    displayMessages();
  }
  @Override
  public void hyperlinkUpdate(HyperlinkEvent e) {
    if (e instanceof FormSubmitEvent) {
      FormSubmitEvent event = (FormSubmitEvent) e;

      // Just pushed the download the file button...
      LOG.debugf("File offer download requested. FileId: {0}", event.getData());

      try {
        String dataStr = event.getData();
        String fileIdEncoded = dataStr.substring(dataStr.indexOf("=") + 1).trim();
        String fileId = URLDecoder.decode(fileIdEncoded, "UTF-8");
        downloadFileOffer(fileId);
      } catch (UnsupportedEncodingException uee) {
        throw new RuntimeException(uee); // impossible
      }
    } else if (HyperlinkEvent.EventType.ACTIVATED == e.getEventType()) {
      handleLinkClick(e.getDescription(), e.getURL());
    }
  }
  private void displayMessages(boolean friendSignedOff) {
    String chatDoc =
        ChatDocumentBuilder.buildChatText(
            messages, currentChatState, conversationName, friendSignedOff);
    LOG.debugf("Chat doc: {0}", chatDoc);
    final JScrollBar verticalScrollBar = conversationScroll.getVerticalScrollBar();
    final int scrollValue = verticalScrollBar.getValue();
    editor.setText(chatDoc);

    // LWC-2262: If the scroll bar was moved above the bottom of the scrollpane, reset the value of
    // the bar to where it was before the text was updated.  This needs to be issued to the end of
    // the
    // queue because the actual repainting/resizing of the scrollbar happens later in a
    // task added to the EDT by the plaf listener of the editor's document.
    // A better fix for this behavior may be possible
    if (verticalScrollBar.getMaximum()
        > (scrollValue + verticalScrollBar.getVisibleAmount() + PADDING)) {
      SwingUtilities.invokeLater(
          new Runnable() {
            @Override
            public void run() {
              verticalScrollBar.setValue(scrollValue);
            }
          });
    } else {
      SwingUtilities.invokeLater(
          new Runnable() {
            @Override
            public void run() {
              verticalScrollBar.setValue(verticalScrollBar.getMaximum());
            }
          });
    }

    decorateFileOfferButtons();

    chatWrapper.repaint();
  }