/** * 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); }
/** * 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(); }