Merge remote-tracking branch 'origin/master'

fix-message-formatting
Danny van Heumen 12 years ago
commit 192b744196

1
.gitignore vendored

@ -11,3 +11,4 @@ sip-communicator.utest.bin
release
lib/accounts.properties
.DS_Store
nbproject/private

Binary file not shown.

@ -0,0 +1,29 @@
auxiliary.org-netbeans-modules-editor-indent.CodeStyle.project.expand-tabs=true
auxiliary.org-netbeans-modules-editor-indent.CodeStyle.project.indent-shift-width=4
auxiliary.org-netbeans-modules-editor-indent.CodeStyle.project.spaces-per-tab=4
auxiliary.org-netbeans-modules-editor-indent.CodeStyle.project.tab-size=8
auxiliary.org-netbeans-modules-editor-indent.CodeStyle.project.text-limit-width=80
auxiliary.org-netbeans-modules-editor-indent.CodeStyle.project.text-line-wrap=none
auxiliary.org-netbeans-modules-editor-indent.CodeStyle.usedProfile=project
auxiliary.org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.alignMultilineImplements=true
auxiliary.org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.alignMultilineThrows=true
auxiliary.org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.classDeclBracePlacement=NEW_LINE
auxiliary.org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.expand-tabs=true
auxiliary.org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.importGroupsOrder=*
auxiliary.org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.indent-shift-width=4
auxiliary.org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.methodDeclBracePlacement=NEW_LINE
auxiliary.org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.otherBracePlacement=NEW_LINE
auxiliary.org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.placeCatchOnNewLine=true
auxiliary.org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.placeElseOnNewLine=true
auxiliary.org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.placeFinallyOnNewLine=true
auxiliary.org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.placeWhileOnNewLine=true
auxiliary.org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.spaces-per-tab=4
auxiliary.org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.tab-size=8
auxiliary.org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.text-limit-width=80
auxiliary.org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.text-line-wrap=words
auxiliary.org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.usePackageImport=true
auxiliary.org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.useSingleClassImport=false
auxiliary.org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.wrapExtendsImplementsKeyword=WRAP_ALWAYS
auxiliary.org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.wrapExtendsImplementsList=WRAP_ALWAYS
auxiliary.org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.wrapThrowsKeyword=WRAP_ALWAYS
auxiliary.org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.wrapThrowsList=WRAP_ALWAYS

@ -720,23 +720,24 @@ identity cannot<br> be automatically verified. \
Do you want to continue connecting?<br><br> \
For more information, click "Show Certificate".</html>
service.gui.CONTINUE_ANYWAY=Continue anyway
service.gui.CERT_INFO_ISSUED_TO=<html><b>Issued To</b></html>
service.gui.CERT_INFO_CHAIN=Certificate Chain:
service.gui.CERT_INFO_ISSUED_TO=Issued To
service.gui.CERT_INFO_CN=Common Name:
service.gui.CERT_INFO_O=Organization:
service.gui.CERT_INFO_C=Country Name:
service.gui.CERT_INFO_ST=State or Province Name:
service.gui.CERT_INFO_L=Locality Name:
service.gui.CERT_INFO_ISSUED_BY=<html><b>Issued By</b></html>
service.gui.CERT_INFO_ISSUED_BY=Issued By
service.gui.CERT_INFO_OU=Organizational Unit:
service.gui.CERT_INFO_VALIDITY=<html><b>Validity</b></html>
service.gui.CERT_INFO_VALIDITY=Validity
service.gui.CERT_INFO_ISSUED_ON=Issued On:
service.gui.CERT_INFO_EXPIRES_ON=Expires On:
service.gui.CERT_INFO_FINGERPRINTS=<html><b>Fingerprints</b></html>
service.gui.CERT_INFO_CERT_DETAILS=<html><b>Certificate Info</b></html>
service.gui.CERT_INFO_FINGERPRINTS=Fingerprints
service.gui.CERT_INFO_CERT_DETAILS=Certificate Info
service.gui.CERT_INFO_SER_NUM=Serial Number:
service.gui.CERT_INFO_VER=Version:
service.gui.CERT_INFO_SIGN_ALG=Signature Algorithm:
service.gui.CERT_INFO_PUB_KEY_INFO=<html><b>Public Key Info</b></html>
service.gui.CERT_INFO_PUB_KEY_INFO=Public Key Info
service.gui.CERT_INFO_ALG=Algorithm:
service.gui.CERT_INFO_PUB_KEY=Public Key:
service.gui.CERT_INFO_KEY_BYTES_PRINT={0} bytes: {1}
@ -1702,8 +1703,11 @@ plugin.reconnectplugin.NETWORK_DOWN=Network connectivity lost!
plugin.chatconfig.TITLE=Chat
plugin.chatconfig.replacement.TITLE=Image/Video:
plugin.chatconfig.replacement.ENABLE_SMILEY_STATUS=Enable smiley replacement
plugin.chatconfig.replacement.ENABLE_REPLACEMENT_STATUS=Enable Image/Video replacement
plugin.chatconfig.replacement.ENABLE_REPLACEMENT_PROPOSAL=Show proposals for Image/Video replacement
plugin.chatconfig.replacement.REPLACEMENT_TITLE=Image/Video replacement
plugin.chatconfig.replacement.ENABLE_REPLACEMENT_STATUS=Enable
plugin.chatconfig.replacement.ENABLE_REPLACEMENT_PROPOSAL=Disable (show preview link)
plugin.chatconfig.replacement.DISABLE_REPLACEMENT=Disable
plugin.chatconfig.replacement.CONFIGURE_REPLACEMENT=Change Image/Video replacement settings
plugin.chatconfig.replacement.REPLACEMENT_SOURCES=Sources:
plugin.chatconfig.spellcheck.TITLE=SpellCheck

@ -1674,7 +1674,7 @@ private void initializeUserInterfaceHierarchy()
settingsPanel.add(recordButton);
if (showHideVideoButton != null)
settingsPanel.add(showHideVideoButton);
if (mergeButton != null)
if (transferCallButton != null)
settingsPanel.add(transferCallButton);
if (videoButton != null)
settingsPanel.add(videoButton);

@ -118,7 +118,14 @@ public OneToOneCallPanel(
addCallPeerPanel(callPeer, uiVideoHandler);
setPreferredSize(new Dimension(400, 400));
int preferredHeight = 400;
if(GuiActivator.getConfigurationService().getBoolean(
OneToOneCallPeerPanel.HIDE_PLACEHOLDER_PIC_PROP,
false))
{
preferredHeight = 128;
}
setPreferredSize(new Dimension(400, preferredHeight));
setTransferHandler(new CallTransferHandler(call));
this.callContainer.addPropertyChangeListener(
@ -457,4 +464,4 @@ public void updateHoldButtonState()
{
callContainer.updateHoldButtonState();
}
}
}

@ -60,6 +60,13 @@ public class OneToOneCallPeerPanel
*/
private static final long serialVersionUID = 0L;
/**
* Property to disable showing the dummy picture for the peer when no
* streams present.
*/
public static final String HIDE_PLACEHOLDER_PIC_PROP
= "net.java.sip.communicator.impl.gui.main.call.HIDE_PLACEHOLDER_PIC";
/**
* The <tt>CallPeer</tt>, which is rendered in this panel.
*/
@ -277,7 +284,15 @@ public OneToOneCallPeerPanel(
detailsChangeListener);
securityPanel = SecurityPanel.create(this, callPeer, null);
photoLabel = new JLabel(getPhotoLabelIcon());
ImageIcon icon = getPhotoLabelIcon();
if(icon != null)
{
photoLabel = new JLabel(icon);
}
else
{
photoLabel = new JLabel();
}
center = createCenter();
statusBar = createStatusBar();
@ -345,6 +360,21 @@ public OneToOneCallPeerPanel(
updateViewFromModel();
}
/**
* Set size of the {@link #photoLabel}
*/
private void sizePhotoLabel()
{
if(photoLabel.getIcon() != null)
{
photoLabel.setPreferredSize(new Dimension(90, 90));
}
else
{
photoLabel.setPreferredSize(new Dimension(0, 0));
}
}
/**
* Creates the <tt>Component</tt> hierarchy of the central area of this
* <tt>CallPeerPanel</tt> which displays the photo of the <tt>CallPeer</tt>
@ -352,7 +382,7 @@ public OneToOneCallPeerPanel(
*/
private VideoContainer createCenter()
{
photoLabel.setPreferredSize(new Dimension(90, 90));
sizePhotoLabel();
return createVideoContainer(photoLabel);
}
@ -584,6 +614,22 @@ public String getPeerName()
return peerName;
}
/**
* Tests a provided boolean property name, returning false if it should be
* hidden.
*
* @param componentHidePropertyName the name of the boolean property to
* check.
* @return false if the component should be hidden, true otherwise.
*
*/
private boolean isComponentEnabled(String componentHidePropertyName)
{
return !GuiActivator.getConfigurationService().getBoolean(
componentHidePropertyName,
false);
}
/**
* Gets the <tt>Icon</tt> to be displayed in {@link #photoLabel}.
*
@ -592,7 +638,7 @@ public String getPeerName()
private ImageIcon getPhotoLabelIcon()
{
return
(peerImage == null)
(peerImage == null && isComponentEnabled(HIDE_PLACEHOLDER_PIC_PROP))
? new ImageIcon(
ImageLoader.getImage(ImageLoader.DEFAULT_USER_PHOTO))
: peerImage;
@ -677,10 +723,18 @@ public void loadSkin()
if(peerImage == null)
{
photoLabel.setIcon(
new ImageIcon(
ImageLoader.getImage(
ImageLoader.DEFAULT_USER_PHOTO)));
if(isComponentEnabled(HIDE_PLACEHOLDER_PIC_PROP))
{
photoLabel.setIcon(
new ImageIcon(
ImageLoader.getImage(
ImageLoader.DEFAULT_USER_PHOTO)));
}
else
{
photoLabel.setIcon(null);
}
sizePhotoLabel();
}
}
@ -1108,6 +1162,7 @@ public void setPeerImage(byte[] image)
public void run()
{
photoLabel.setIcon(peerImage);
sizePhotoLabel();
photoLabel.repaint();
}
});
@ -1115,6 +1170,7 @@ public void run()
else
{
photoLabel.setIcon(peerImage);
sizePhotoLabel();
photoLabel.repaint();
}
}
@ -1582,4 +1638,4 @@ public void setInterested(boolean value)
this.interested = value;
}
}
}
}

@ -28,6 +28,7 @@
import net.java.sip.communicator.impl.gui.main.chat.history.*;
import net.java.sip.communicator.impl.gui.main.chat.menus.*;
import net.java.sip.communicator.impl.gui.utils.*;
import net.java.sip.communicator.impl.gui.utils.Constants;
import net.java.sip.communicator.plugin.desktoputil.*;
import net.java.sip.communicator.plugin.desktoputil.SwingWorker;
import net.java.sip.communicator.service.gui.*;
@ -41,6 +42,8 @@
import net.java.sip.communicator.util.skin.*;
import org.jitsi.util.*;
import org.osgi.framework.*;
/**
* The <tt>ChatConversationPanel</tt> is the panel, where all sent and received
* messages appear. All data is stored in an HTML document. An external CSS file
@ -136,11 +139,26 @@ public class ChatConversationPanel
*/
private String currentHref;
/**
* The currently shown href, is it an img element.
*/
private boolean isCurrentHrefImg = false;
/**
* The copy link item, contained in the right mouse click menu.
*/
private final JMenuItem copyLinkItem;
/**
* The copy link item, contained in the right mouse click menu.
*/
private final JMenuItem configureReplacementItem;
/**
* The configure replacement item separator.
*/
private final JSeparator configureReplacementSeparator = new JSeparator();
/**
* The open link item, contained in the right mouse click menu.
*/
@ -310,6 +328,30 @@ public void actionPerformed(ActionEvent e)
GuiActivator.getResources().getI18nMnemonic(
"service.gui.COPY_LINK"));
configureReplacementItem = new JMenuItem(
GuiActivator.getResources().getI18NString(
"plugin.chatconfig.replacement.CONFIGURE_REPLACEMENT"),
GuiActivator.getResources().getImage(
"service.gui.icons.CONFIGURE_ICON"));
configureReplacementItem.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
final ConfigurationContainer configContainer
= GuiActivator.getUIService().getConfigurationContainer();
ConfigurationForm chatConfigForm = getChatConfigForm();
if (chatConfigForm != null)
{
configContainer.setSelected(chatConfigForm);
configContainer.setVisible(true);
}
}
});
this.isSimpleTheme = ConfigurationUtils.isChatSimpleThemeEnabled();
/*
@ -1171,11 +1213,14 @@ public void hyperlinkUpdate(HyperlinkEvent e)
{
String href = e.getDescription();
this.isCurrentHrefImg
= e.getSourceElement().getName().equals("img");
this.currentHref = href;
}
else if (e.getEventType() == HyperlinkEvent.EventType.EXITED)
{
this.currentHref = "";
this.isCurrentHrefImg = false;
}
}
@ -1228,7 +1273,7 @@ else if ((e.getModifiers() & InputEvent.BUTTON1_MASK) != 0
catch (URISyntaxException e1)
{
logger.error("Failed to open hyperlink in chat window. " +
"Error was: Invalid URL - " + currentHref);
"Error was: Invalid URL - " + currentHref);
return;
}
if("jitsi".equals(uri.getScheme()))
@ -1261,12 +1306,19 @@ private void openContextMenu(Point p)
rightButtonMenu.insert(openLinkItem, 0);
rightButtonMenu.insert(copyLinkItem, 1);
rightButtonMenu.insert(copyLinkSeparator, 2);
if(isCurrentHrefImg)
{
rightButtonMenu.insert(configureReplacementItem, 3);
rightButtonMenu.insert(configureReplacementSeparator, 4);
}
}
else
{
rightButtonMenu.remove(openLinkItem);
rightButtonMenu.remove(copyLinkItem);
rightButtonMenu.remove(copyLinkSeparator);
rightButtonMenu.remove(configureReplacementItem);
rightButtonMenu.remove(configureReplacementSeparator);
}
if (chatTextPane.getSelectedText() != null)
@ -1956,6 +2008,60 @@ private String getElementContent(String elementId, String message)
return null;
}
/**
* Returns the first available advanced configuration form.
*
* @return the first available advanced configuration form
*/
public static ConfigurationForm getChatConfigForm()
{
// General configuration forms only.
String osgiFilter = "("
+ ConfigurationForm.FORM_TYPE
+ "="+ConfigurationForm.GENERAL_TYPE+")";
ServiceReference[] confFormsRefs = null;
try
{
confFormsRefs = GuiActivator.bundleContext
.getServiceReferences(
ConfigurationForm.class.getName(),
osgiFilter);
}
catch (InvalidSyntaxException ex)
{}
String chatConfigFormClassName =
"net.java.sip.communicator.plugin.chatconfig.ChatConfigPanel";
if(confFormsRefs != null)
{
for (int i = 0; i < confFormsRefs.length; i++)
{
ConfigurationForm form
= (ConfigurationForm) GuiActivator.bundleContext
.getService(confFormsRefs[i]);
if (form instanceof LazyConfigurationForm)
{
LazyConfigurationForm lazyConfigForm
= (LazyConfigurationForm) form;
if (lazyConfigForm.getFormClassName()
.equals(chatConfigFormClassName))
return form;
}
else if (form.getClass().getName()
.equals(chatConfigFormClassName))
{
return form;
}
}
}
return null;
}
/**
* Extends SIPCommHTMLEditorKit to keeps track of created ImageView for
* the gif images in order to flush them whenever they are no longer visible
@ -2322,6 +2428,24 @@ private void processText(String plainText,
msgBuff.append(group);
}
}
else if (isProposalEnabled)
{
msgBuff.append(group);
msgBuff.append(
"</A> <A href=\"jitsi://"
+ showPreview.getClass().getName()
+ "/SHOWPREVIEW?" + messageID + "#"
+ linkCounter + "\">"
+ GuiActivator.getResources().
getI18NString("service.gui.SHOW_PREVIEW"));
showPreview.getMsgIDandPositionToLink()
.put(
messageID + "#" + linkCounter++, group);
showPreview.getLinkToReplacement()
.put(
group, temp);
}
else if (isEnabled && isEnabledForSource)
{
if (isDirectImage)
@ -2355,24 +2479,6 @@ else if (isEnabled && isEnabledForSource)
msgBuff.append("\"></IMG>");
}
}
else if (isProposalEnabled)
{
msgBuff.append(group);
msgBuff.append(
"</A> <A href=\"jitsi://"
+ showPreview.getClass().getName()
+ "/SHOWPREVIEW?" + messageID + "#"
+ linkCounter + "\">"
+ GuiActivator.getResources().
getI18NString("service.gui.SHOW_PREVIEW"));
showPreview.getMsgIDandPositionToLink()
.put(
messageID + "#" + linkCounter++, group);
showPreview.getLinkToReplacement()
.put(
group, temp);
}
else
{
msgBuff.append(group);

@ -15,12 +15,9 @@
import net.java.sip.communicator.plugin.desktoputil.*;
import net.java.sip.communicator.plugin.desktoputil.SwingWorker;
import net.java.sip.communicator.service.gui.*;
import net.java.sip.communicator.service.replacement.*;
import net.java.sip.communicator.service.replacement.directimage.*;
import net.java.sip.communicator.util.*;
import org.jitsi.service.configuration.*;
public class ShowPreviewDialog
extends SIPCommDialog
implements ActionListener,
@ -38,9 +35,6 @@ public class ShowPreviewDialog
private static final Logger logger
= Logger.getLogger(ShowPreviewDialog.class);
ConfigurationService cfg
= GuiActivator.getConfigurationService();
/**
* The Ok button.
*/
@ -54,12 +48,7 @@ public class ShowPreviewDialog
/**
* Checkbox that indicates whether or not to show this dialog next time.
*/
private final JCheckBox enableReplacementProposal;
/**
* Checkbox that indicates whether or not to show previews automatically
*/
private final JCheckBox enableReplacement;
private final JCheckBox configureReplacement;
/**
* The <tt>ChatConversationPanel</tt> that this dialog is associated with.
@ -147,23 +136,14 @@ public class ShowPreviewDialog
warningPanel.add(Box.createHorizontalStrut(10));
warningPanel.add(descriptionMsg);
enableReplacement
= new JCheckBox(
configureReplacement
= new SIPCommCheckBox(
GuiActivator.getResources().getI18NString(
"plugin.chatconfig.replacement.ENABLE_REPLACEMENT_STATUS"));
enableReplacement.setOpaque(false);
enableReplacement.setSelected(
cfg.getBoolean(ReplacementProperty.REPLACEMENT_ENABLE, true));
enableReplacementProposal
= new JCheckBox(
GuiActivator.getResources().getI18NString(
"plugin.chatconfig.replacement.ENABLE_REPLACEMENT_PROPOSAL"));
enableReplacementProposal.setOpaque(false);
"plugin.chatconfig.replacement.CONFIGURE_REPLACEMENT"));
JPanel checkBoxPanel = new TransparentPanel();
checkBoxPanel.setLayout(new BoxLayout(checkBoxPanel, BoxLayout.Y_AXIS));
checkBoxPanel.add(enableReplacement);
checkBoxPanel.add(enableReplacementProposal);
JPanel checkBoxPanel = new TransparentPanel(
new FlowLayout(FlowLayout.CENTER));
checkBoxPanel.add(configureReplacement);
JPanel buttonsPanel
= new TransparentPanel(new FlowLayout(FlowLayout.CENTER));
@ -186,10 +166,6 @@ public void actionPerformed(ActionEvent arg0)
{
if (arg0.getSource().equals(okButton))
{
cfg.setProperty(ReplacementProperty.REPLACEMENT_ENABLE,
enableReplacement.isSelected());
cfg.setProperty(ReplacementProperty.REPLACEMENT_PROPOSAL
, enableReplacementProposal.isSelected());
SwingWorker worker = new SwingWorker()
{
/**
@ -275,6 +251,26 @@ else if (arg0.getSource().equals(cancelButton))
{
this.setVisible(false);
}
// Shows chat config panel
if(configureReplacement.isSelected())
{
ConfigurationContainer configContainer
= GuiActivator.getUIService().getConfigurationContainer();
ConfigurationForm chatConfigForm =
ChatConversationPanel.getChatConfigForm();
if(chatConfigForm != null)
{
configContainer.setSelected(chatConfigForm);
configContainer.setVisible(true);
}
// reset for next dialog appearance
configureReplacement.setSelected(false);
}
}
@Override
@ -283,11 +279,6 @@ public void chatLinkClicked(URI url)
String action = url.getPath();
if (action.equals("/SHOWPREVIEW"))
{
enableReplacement.setSelected(
cfg.getBoolean(ReplacementProperty.REPLACEMENT_ENABLE, true));
enableReplacementProposal.setSelected(
cfg.getBoolean(ReplacementProperty.REPLACEMENT_PROPOSAL, true));
currentMessageID = url.getQuery();
currentLinkPosition = url.getFragment();
@ -325,4 +316,16 @@ Map<String, String> getLinkToReplacement()
{
return linkToReplacement;
}
/**
* All functions implemented in this method will be invoked when user
* presses the Escape key.
*
* @param escaped <tt>true</tt> if this frame has been closed by pressing
* the Esc key; otherwise, <tt>false</tt>
*/
protected void close(boolean escaped)
{
cancelButton.doClick();
}
}

@ -253,6 +253,7 @@ public void run()
this.configList.setSelectedIndex(0);
}
super.setVisible(isVisible);
super.toFront();
}
/**

@ -87,7 +87,7 @@ public T getPeer(String sid)
{
for(T peer : getCallPeerList())
{
if (peer.getSID().equals(sid))
if (peer.getSID() != null && peer.getSID().equals(sid))
return peer;
}
return null;

@ -393,6 +393,16 @@ public void interceptPacket(Packet packet)
caps.getNode() + "#" + caps.getVersion(),
this);
// Remove old capabilities extension if present
PacketExtension oldCaps
= packet.getExtension(
CapsPacketExtension.ELEMENT_NAME,
CapsPacketExtension.NAMESPACE);
if (oldCaps != null)
{
packet.removeExtension(oldCaps);
}
// Put new capabilities extension
packet.addExtension(caps);
}
}

@ -232,7 +232,24 @@ public void addChildExtension(PacketExtension childExtension)
else if(childExtension instanceof CandidatePacketExtension)
addCandidate((CandidatePacketExtension) childExtension);
else if (childExtension instanceof DtlsFingerprintPacketExtension)
else
super.addChildExtension(childExtension);
}
/**
* Checks whether an 'rtcp-mux' extension has been added to this
* <tt>IceUdpTransportPacketExtension</tt>.
* @return <tt>true</tt> if this <tt>IceUdpTransportPacketExtension</tt>
* has a child with the 'rtcp-mux' name.
*/
public boolean isRtcpMux()
{
for (PacketExtension packetExtension : getChildExtensions())
{
if (RtcpmuxPacketExtension.ELEMENT_NAME
.equals(packetExtension.getElementName()))
return true;
}
return false;
}
}

@ -156,6 +156,13 @@ public JingleIQProvider()
ConferenceDescriptionPacketExtension.NAMESPACE,
new DefaultPacketExtensionProvider<CallIdPacketExtension>(
CallIdPacketExtension.class));
//rtcp-mux
providerManager.addExtensionProvider(
RtcpmuxPacketExtension.ELEMENT_NAME,
IceUdpTransportPacketExtension.NAMESPACE,
new DefaultPacketExtensionProvider<RtcpmuxPacketExtension>(
RtcpmuxPacketExtension.class));
}
/**

@ -0,0 +1,31 @@
/*
* Jitsi, the OpenSource Java VoIP and Instant Messaging client.
*
* Distributable under LGPL license.
* See terms of license at gnu.org.
*/
package net.java.sip.communicator.impl.protocol.jabber.extensions.jingle;
import net.java.sip.communicator.impl.protocol.jabber.extensions.*;
/**
* An 'rtcp-mux' extension.
* @author Boris Grozev
*/
public class RtcpmuxPacketExtension
extends AbstractPacketExtension
{
/**
* The name of the "encryption" element.
*/
public static final String ELEMENT_NAME = "rtcp-mux";
/**
* Creates a new instance of <tt>RtcpmuxPacketExtension</tt>.
*/
public RtcpmuxPacketExtension()
{
super(null, ELEMENT_NAME);
}
}

@ -0,0 +1,163 @@
/*
* Jitsi, the OpenSource Java VoIP and Instant Messaging client.
*
* Distributable under LGPL license.
* See terms of license at gnu.org.
*/
package net.java.sip.communicator.impl.protocol.jabber.extensions.jitsimeet;
import net.java.sip.communicator.impl.protocol.jabber.extensions.*;
import org.jivesoftware.smack.provider.*;
/**
* Packet extension used by Jitsi Meet to advertise local media SSRCs in MUC
* presence.
*
* @author Pawel Domas
*/
public class MediaPresenceExtension
extends AbstractPacketExtension
{
/**
* The namespace of this packet extension.
*/
public static final String NAMESPACE = "http://estos.de/ns/mjs";
/**
* XML element name of this packet extension.
*/
public static final String ELEMENT_NAME = "media";
/**
* Creates an <tt>MediaPresenceExtension</tt> instance.
*
*/
public MediaPresenceExtension()
{
super(NAMESPACE, ELEMENT_NAME);
}
/**
* Registers packet Jitsi Meet media presence packet extensions in given
* <tt>providerManager</tt>.
*
* @param providerManager the <tt>ProviderManager</tt> to which media
* presence extensions will be registered to.
*/
public static void registerExtensions(ProviderManager providerManager)
{
// <media>
providerManager.addExtensionProvider(
MediaPresenceExtension.ELEMENT_NAME,
MediaPresenceExtension.NAMESPACE,
new DefaultPacketExtensionProvider<MediaPresenceExtension>(
MediaPresenceExtension.class));
// <source>
providerManager.addExtensionProvider(
MediaPresenceExtension.Source.ELEMENT_NAME,
MediaPresenceExtension.Source.NAMESPACE,
new DefaultPacketExtensionProvider<Source>(
Source.class));
}
/**
* Source extension element that specifies into about media SSRC.
*/
public static class Source
extends AbstractPacketExtension
{
/**
* Source XML element name.
*/
public final static String ELEMENT_NAME = "source";
/**
* No namespace attached.
*/
public final static String NAMESPACE = "";
/**
* SSRC media type attribute name. Can be 'audio' or 'video'.
*/
public final static String MEDIA_TYPE_ATTR_NAME = "type";
/**
* SSRC number attribute name.
*/
public final static String SOURCE_ATTR_NAME = "ssrc";
/**
* Media direction as used in SDP('sendrecv', 'recvonly', 'sendonly').
*/
public final static String DIRECTION_ATTR_NAME = "direction";
/**
* Creates new instance of <tt>Source</tt> packet extension with default
* 'sendrecv' direction set.
*/
public Source()
{
super(NAMESPACE, ELEMENT_NAME);
// Default direction
setDirection("sendrecv");
}
/**
* Returns media direction
* (values like used in SDP 'sendrecv', 'recvonly'...).
*/
public String getDirection()
{
return getAttributeAsString(DIRECTION_ATTR_NAME);
}
/**
* Returns media synchronization source identifier.
*/
public String getSSRC()
{
return getAttributeAsString(SOURCE_ATTR_NAME);
}
/**
* Sets media type of the media represented by this source packet
* extensions.
* @param mediaType media type string('audio' or 'video').
*/
public void setMediaType(String mediaType)
{
setAttribute(MEDIA_TYPE_ATTR_NAME, mediaType);
}
/**
* Direction of the media represented by this source packet extension.
* @param direction media direction like used in SDP
* ('sendrecv, 'recvonly'...).
*/
public void setDirection(String direction)
{
setAttribute(DIRECTION_ATTR_NAME, direction);
}
/**
* Sets synchronization source identifier of the media represented by
* this source packet extension.
* @param ssrc synchronization source identifier to set.
*/
public void setSSRC(String ssrc)
{
setAttribute(SOURCE_ATTR_NAME, ssrc);
}
/**
* @return type of the media(audio or video) represented by this source
* packet extension.
*/
public String getMediaType()
{
return getAttributeAsString(MEDIA_TYPE_ATTR_NAME);
}
}
}

@ -0,0 +1,104 @@
/*
* Jitsi, the OpenSource Java VoIP and Instant Messaging client.
*
* Distributable under LGPL license.
* See terms of license at gnu.org.
*/
package net.java.sip.communicator.impl.protocol.jabber.extensions.rayo;
import net.java.sip.communicator.impl.protocol.jabber.extensions.*;
import org.jivesoftware.smack.packet.*;
/**
* 'End' Rayo packet extension used to notify the client about call ended event.
*
* @author Pawel Domas
*/
public class EndExtension
extends AbstractPacketExtension
{
/**
* XML element name of this extension.
*/
public static final String ELEMENT_NAME = "end";
/**
* End reason.
*/
private ReasonExtension reason;
/**
* Creates new instance.
*/
protected EndExtension()
{
super(RayoIqProvider.NAMESPACE, ELEMENT_NAME);
}
/**
* Checks if given <tt>elementName</tt> is valid end reason element.
* @param elementName the XML element name to check.
* @return <tt>true</tt> if given <tt>elementName</tt> is valid end reason
* element.
*/
public static boolean isValidReason(String elementName)
{
return ReasonExtension.BUSY.equals(elementName)
|| ReasonExtension.ERROR.equals(elementName)
|| ReasonExtension.HANGUP.equals(elementName)
|| ReasonExtension.HANGUP_COMMND.equals(elementName)
|| ReasonExtension.REJECTED.equals(elementName)
|| ReasonExtension.TIMEOUT.equals(elementName);
}
/**
* Returns {@link ReasonExtension} associated with this instance.
* @return {@link ReasonExtension} associated with this instance.
*/
public ReasonExtension getReason()
{
return reason;
}
/**
* Sets new {@link ReasonExtension} for this <tt>EndExtension</tt> instance.
* @param newReason the new {@link ReasonExtension} to set.
*/
public void setReason(ReasonExtension newReason)
{
if (this.reason != null)
{
getChildExtensions().remove(this.reason);
}
this.reason = newReason;
addChildExtension(newReason);
}
/**
* Creates 'Presence' packet containing call ended Rayo notification that
* contains specified end <tt>reason</tt>.
* @param from source JID of this event.
* @param to destination JID.
* @param reason call end reason string. One of {@link ReasonExtension}
* static constants.
* @return 'Presence' packet containing call ended Rayo notification.
*/
public static Presence createEnd(String from, String to, String reason)
{
Presence presence = new Presence(Presence.Type.unavailable);
presence.setFrom(from);
presence.setTo(to);
EndExtension end = new EndExtension();
end.setReason(new ReasonExtension(reason));
presence.addExtension(end);
return presence;
}
}

@ -0,0 +1,78 @@
/*
* Jitsi, the OpenSource Java VoIP and Instant Messaging client.
*
* Distributable under LGPL license.
* See terms of license at gnu.org.
*/
package net.java.sip.communicator.impl.protocol.jabber.extensions.rayo;
import net.java.sip.communicator.impl.protocol.jabber.extensions.*;
/**
* Header packet extension optionally included in {@link RayoIqProvider.RayoIq}.
* Holds 'name' and 'value' attributes.
*
* @author Pawel Domas
*/
public class HeaderExtension
extends AbstractPacketExtension
{
/**
* XML element name.
*/
public static final String ELEMENT_NAME = "header";
/**
* The name of 'name' attribute.
*/
public static final String NAME_ATTR_NAME = "name";
/**
* The name of 'value' attribute.
*/
public static final String VALUE_ATTR_NAME = "value";
/**
* Creates new instance of <tt>HeaderPacketExtension</tt>.
*/
public HeaderExtension()
{
super(null, ELEMENT_NAME);
}
/**
* Return the value of 'name' attribute.
* @return the value of 'name' attribute.
*/
public String getName()
{
return getAttributeAsString(NAME_ATTR_NAME);
}
/**
* Sets new value for 'name' attribute of this extension.
* @param name the new value to set for 'name' attribute.
*/
public void setName(String name)
{
setAttribute(NAME_ATTR_NAME, name);
}
/**
* Returns the value of 'value' attribute.
* @return the value of 'value' attribute.
*/
public String getValue()
{
return getAttributeAsString(VALUE_ATTR_NAME);
}
/**
* Sets new value for the 'value' attribute.
* @param value new value for the 'value' attribute to set.
*/
public void setValue(String value)
{
setAttribute(VALUE_ATTR_NAME, value);
}
}

@ -0,0 +1,587 @@
/*
* Jitsi, the OpenSource Java VoIP and Instant Messaging client.
*
* Distributable under LGPL license.
* See terms of license at gnu.org.
*/
package net.java.sip.communicator.impl.protocol.jabber.extensions.rayo;
import net.java.sip.communicator.impl.protocol.jabber.extensions.*;
import org.jitsi.util.*;
import org.jivesoftware.smack.packet.*;
import org.jivesoftware.smack.provider.*;
import org.xmlpull.v1.*;
import java.util.*;
/**
* Provider handles parsing of Rayo IQ stanzas and converting objects back to
* their XML representation.
*
* FIXME: implements only the minimum required to start and hang up a call
*
* @author Pawel Domas
*/
public class RayoIqProvider
implements IQProvider
{
/**
* Rayo namespace.
*/
public final static String NAMESPACE = "urn:xmpp:rayo:1";
/**
* Registers this IQ provider into given <tt>ProviderManager</tt>.
* @param providerManager the <tt>ProviderManager</tt> to which this
* instance wil be bound to.
*/
public void registerRayoIQs(ProviderManager providerManager)
{
// <dial>
providerManager.addIQProvider(
DialIq.ELEMENT_NAME,
NAMESPACE,
this);
// <ref>
providerManager.addIQProvider(
RefIq.ELEMENT_NAME,
NAMESPACE,
this);
// <hangup>
providerManager.addIQProvider(
HangUp.ELEMENT_NAME,
NAMESPACE,
this);
// <end> presence extension
providerManager.addExtensionProvider(
EndExtension.ELEMENT_NAME,
NAMESPACE,
new DefaultPacketExtensionProvider<EndExtension>(
EndExtension.class));
// <header> extension
providerManager.addExtensionProvider(
HeaderExtension.ELEMENT_NAME,
"",
new DefaultPacketExtensionProvider<HeaderExtension>(
HeaderExtension.class));
}
/**
* {@inheritDoc}
*/
@Override
public IQ parseIQ(XmlPullParser parser)
throws Exception
{
String namespace = parser.getNamespace();
// Check the namespace
if (!NAMESPACE.equals(namespace))
{
return null;
}
String rootElement = parser.getName();
RayoIq iq;
DialIq dial;
RefIq ref;
//End end = null;
if (DialIq.ELEMENT_NAME.equals(rootElement))
{
iq = dial = new DialIq();
String src = parser.getAttributeValue("", DialIq.SRC_ATTR_NAME);
String dst = parser.getAttributeValue("", DialIq.DST_ATTR_NAME);
// Destination is mandatory
if (StringUtils.isNullOrEmpty(dst))
return null;
dial.setSource(src);
dial.setDestination(dst);
}
else if (RefIq.ELEMENT_NAME.equals(rootElement))
{
iq = ref = new RefIq();
String uri = parser.getAttributeValue("", RefIq.URI_ATTR_NAME);
if (StringUtils.isNullOrEmpty(uri))
return null;
ref.setUri(uri);
}
else if (HangUp.ELEMENT_NAME.equals(rootElement))
{
iq = new HangUp();
}
/*else if (End.ELEMENT_NAME.equals(rootElement))
{
iq = end = new End();
}*/
else
{
return null;
}
boolean done = false;
HeaderExtension header = null;
//ReasonExtension reason = null;
while (!done)
{
switch (parser.next())
{
case XmlPullParser.END_TAG:
{
String name = parser.getName();
if (rootElement.equals(name))
{
done = true;
}
else if (HeaderExtension.ELEMENT_NAME.equals(
name))
{
if (header != null)
{
iq.addExtension(header);
header = null;
}
}
/*else if (End.isValidReason(name))
{
if (end != null && reason != null)
{
end.setReason(reason);
reason = null;
}
}*/
break;
}
case XmlPullParser.START_TAG:
{
String name = parser.getName();
if (HeaderExtension.ELEMENT_NAME.equals(name))
{
header = new HeaderExtension();
String nameAttr
= parser.getAttributeValue(
"", HeaderExtension.NAME_ATTR_NAME);
header.setName(nameAttr);
String valueAttr
= parser.getAttributeValue(
"", HeaderExtension.VALUE_ATTR_NAME);
header.setValue(valueAttr);
}
/*else if (End.isValidReason(name))
{
reason = new ReasonPacketExtension(name);
String platformCode
= parser.getAttributeValue(
"", ReasonPacketExtension.PLATFORM_CODE_ATTRIBUTE);
if (!StringUtils.isNullOrEmpty(platformCode))
{
reason.setPlatformCode(platformCode);
}
}*/
break;
}
case XmlPullParser.TEXT:
{
// Parse some text here
break;
}
}
}
return iq;
}
/**
* Base class for all Ray IQs. Takes care of <header /> extension handling
* as well as other functions shared by all IQs.
*/
public static abstract class RayoIq
extends IQ
{
/**
* The XML element name that will be used.
*/
private final String elementName;
/**
* Creates new instance of <tt>RayoIq</tt>.
*
* @param elementName the name of XML element that will be used.
*/
protected RayoIq(String elementName)
{
this.elementName = elementName;
}
/**
* Implementing classes should print their attributes if any in XML
* format to given <tt>out</tt> <tt>StringBuilder</tt>.
* @param out the <tt>StringBuilder</tt> instance used to construct XML
* representation of this element.
*/
protected abstract void printAttributes(StringBuilder out);
/**
* {@inheritDoc}
*/
@Override
public String getChildElementXML()
{
StringBuilder xml = new StringBuilder();
xml.append('<').append(elementName);
xml.append(" xmlns='").append(NAMESPACE).append("' ");
printAttributes(xml);
Collection<PacketExtension> extensions = getExtensions();
if (extensions.size() > 0)
{
xml.append(">");
for (PacketExtension extension : extensions)
{
xml.append(extension.toXML());
}
xml.append("</").append(elementName).append(">");
}
else
{
xml.append("/>");
}
return xml.toString();
}
/**
* Returns value of the header extension with given <tt>name</tt>
* (if any).
* @param name the name of header extension which value we want to
* retrieve.
* @return value of header extension with given <tt>name</tt> if it
* exists or <tt>null</tt> otherwise.
*/
public String getHeader(String name)
{
HeaderExtension header = findHeader(name);
return header != null ? header.getValue() : null;
}
private HeaderExtension findHeader(String name)
{
for(PacketExtension ext: getExtensions())
{
if (ext instanceof HeaderExtension)
{
HeaderExtension header = (HeaderExtension) ext;
if(name.equals(header.getName()))
return header;
}
}
return null;
}
/**
* Adds 'header' extension to this Rayo IQ with given name and value
* attributes.
* @param name the attribute name of the 'header' extension to be added.
* @param value the 'value' attribute of the 'header' extension that
* will be added to this IQ.
*/
public void setHeader(String name, String value)
{
HeaderExtension headerExt = findHeader(name);
if (headerExt == null)
{
headerExt = new HeaderExtension();
headerExt.setName(name);
addExtension(headerExt);
}
headerExt.setValue(value);
}
}
/**
* The 'dial' IQ used to initiate new outgoing call session in Rayo
* protocol.
*/
public static class DialIq
extends RayoIq
{
/**
* The name of XML element for this IQ.
*/
public static final String ELEMENT_NAME = "dial";
/**
* The name of source URI/address attribute. Referred as "source" to
* avoid confusion with "getFrom" and "setFrom" in {@link IQ} class.
*/
public static final String SRC_ATTR_NAME = "from";
/**
* The name of destination URI/address attribute. Referred as "source"
* to avoid confusion with "getFrom" and "setFrom" in {@link IQ} class.
*/
public static final String DST_ATTR_NAME = "to";
/**
* Source URI/address.
*/
private String source;
/**
* Destination URI/address.
*/
private String destination;
/**
* Creates new instance of <tt>DialIq</tt>.
*/
public DialIq()
{
super(DialIq.ELEMENT_NAME);
}
/**
* Creates new <tt>DialIq</tt> for given source and destination
* addresses.
* @param to the destination address/call URI to be used.
* @param from the source address that will be set on
* new <tt>DialIq</tt> instance.
* @return new <tt>DialIq</tt> parametrized with given source and
* destination addresses.
*/
public static DialIq create(String to, String from)
{
DialIq dialIq = new DialIq();
dialIq.setSource(from);
dialIq.setDestination(to);
return dialIq;
}
/**
* Return source address value set on this <tt>DialIq</tt>.
* @return source address value of this <tt>DialIq</tt>.
*/
public String getSource()
{
return source;
}
/**
* Sets new source address value on this <tt>DialIq</tt>.
* @param source the new source address value to be set.
*/
public void setSource(String source)
{
this.source = source;
}
/**
* Returns destination address/call URI associated with this instance.
* @return destination address/call URI associated with this instance.
*/
public String getDestination()
{
return destination;
}
/**
* Sets new destination address/call URI on this <tt>DialIq</tt>.
* @param destination the new destination address/call URI to set.
*/
public void setDestination(String destination)
{
this.destination = destination;
}
/**
* {@inheritDoc}
*/
@Override
protected void printAttributes(StringBuilder out)
{
String src = getSource();
if (!StringUtils.isNullOrEmpty(src))
out.append(SRC_ATTR_NAME).append("='")
.append(src).append("' ");
String dst = getDestination();
if (!StringUtils.isNullOrEmpty(dst))
out.append(DST_ATTR_NAME).append("='")
.append(dst).append("' ");
}
}
/**
* Rayo 'ref' IQ sent by the server as a reply to 'dial' request. Holds
* created call's resource in 'uri' attribute.
*/
public static class RefIq
extends RayoIq
{
/**
* XML element name of <tt>RefIq</tt>.
*/
public static final String ELEMENT_NAME = "ref";
/**
* Name of the URI attribute that stores call resource reference.
*/
public static final String URI_ATTR_NAME = "uri";
/**
* Call resource/uri reference.
*/
private String uri;
/**
* Creates new <tt>RefIq</tt>.
*/
protected RefIq()
{
super(RefIq.ELEMENT_NAME);
}
/**
* Creates new <tt>RefIq</tt> parametrized with given call <tt>uri</tt>.
* @param uri the call URI to be set on newly created <tt>RefIq</tt>.
* @return new <tt>RefIq</tt> parametrized with given call <tt>uri</tt>.
*/
public static RefIq create(String uri)
{
RefIq refIq = new RefIq();
refIq.setUri(uri);
return refIq;
}
/**
* Creates result <tt>RefIq</tt> for given <tt>requestIq</tt>
* parametrized with given call <tt>uri</tt>.
* @param requestIq the request IQ which 'from', 'to' and 'id'
* attributes will be used for constructing result IQ.
* @param uri the call URI that will be included in newly created
* <tt>RefIq</tt>.
* @return result <tt>RefIq</tt> for given <tt>requestIq</tt>
* parametrized with given call <tt>uri</tt>.
*/
public static RefIq createResult(IQ requestIq, String uri)
{
RefIq refIq = create(uri);
refIq.setType(IQ.Type.RESULT);
refIq.setPacketID(requestIq.getPacketID());
refIq.setFrom(requestIq.getTo());
refIq.setTo(requestIq.getFrom());
return refIq;
}
/**
* {@inheritDoc}
*/
@Override
protected void printAttributes(StringBuilder out)
{
String uri = getUri();
if (!StringUtils.isNullOrEmpty(uri))
out.append(URI_ATTR_NAME).append("='")
.append(uri).append("' ");
}
/**
* Sets given call <tt>uri</tt> value on this instance.
* @param uri the call <tt>uri</tt> to be stored in this instance.
*/
public void setUri(String uri)
{
this.uri = uri;
}
/**
* Returns call URI held by this instance.
* @return the call URI held by this instance.
*/
public String getUri()
{
return uri;
}
}
/**
* Rayo hangup IQ is sent by the controlling agent to tell the server that
* call whose resource is mentioned in IQ's 'to' attribute should be
* terminated. Server immediately replies with result IQ which means that
* hangup operation is now scheduled. After it is actually executed presence
* indication with {@link EndExtension} is sent through the presence to
* confirm the operation.
*/
public static class HangUp
extends RayoIq
{
/**
* The name of 'hangup' element.
*/
public static final String ELEMENT_NAME = "hangup";
/**
* Creates new instance of <tt>HangUp</tt> IQ.
*/
protected HangUp()
{
super(ELEMENT_NAME);
}
/**
* Creates new, parametrized instance of {@link HangUp} IQ.
* @param from source JID.
* @param to the destination address/call URI to be ended by this IQ.
* @return new, parametrized instance of {@link HangUp} IQ.
*/
public static HangUp create(String from, String to)
{
HangUp hangUp = new HangUp();
hangUp.setFrom(from);
hangUp.setTo(to);
hangUp.setType(Type.SET);
return hangUp;
}
@Override
protected void printAttributes(StringBuilder out){ }
}
}

@ -0,0 +1,88 @@
/*
* Jitsi, the OpenSource Java VoIP and Instant Messaging client.
*
* Distributable under LGPL license.
* See terms of license at gnu.org.
*/
package net.java.sip.communicator.impl.protocol.jabber.extensions.rayo;
import net.java.sip.communicator.impl.protocol.jabber.extensions.*;
/**
* Rayo 'reason' packet extension.
*
* @author Pawel Domas
*/
public class ReasonExtension
extends AbstractPacketExtension
{
/**
* The name of optional platform code attribute.
*/
public static final String PLATFORM_CODE_ATTRIBUTE = "platform-code";
/**
* Indication that the call ended due to a normal hangup by the remote
* party.
*/
public static final String HANGUP = "hangup";
/**
* Indication that the call ended due to a normal hangup triggered by
* a hangup command.
*/
public static final String HANGUP_COMMND = "hangup-command";
/**
* Indication that the call ended due to a timeout in contacting the remote
* party.
*/
public static final String TIMEOUT = "timeout";
/**
* Indication that the call ended due to being rejected by the remote party
* subsequent to being accepted.
*/
public static final String BUSY = "busy";
/**
* Indication that the call ended due to being rejected by the remote party
* before being accepted.
*/
public static final String REJECTED = "rejected";
/**
* Indication that the call ended due to a system error.
*/
public static final String ERROR = "error";
/**
* Creates an {@link ReasonExtension} instance for the specified
* <tt>namespace</tt> and <tt>elementName</tt>.
*
* @param elementName the name of the element
*/
public ReasonExtension(String elementName)
{
super(null, elementName);
}
/**
* Returns the value of platform code attribute.
* @return the value of platform code attribute.
*/
public String getPlatformCode()
{
return getAttributeAsString(PLATFORM_CODE_ATTRIBUTE);
}
/**
* Sets new value of platform code attribute. Pass <tt>null</tt> to remove.
* @param code new value of platform code attribute. Pass <tt>null</tt> to
* remove.
*/
public void setPlatformCode(String code)
{
setAttribute(PLATFORM_CODE_ATTRIBUTE, code);
}
}

@ -357,10 +357,41 @@ public CallPeerSipImpl invite(Address calleeAddress,
Request invite
= messageFactory.createInviteRequest(calleeAddress, cause);
// Transport preference
String forceTransport = null;
javax.sip.address.URI calleeURI = calleeAddress.getURI();
if(calleeURI.getScheme().toLowerCase().equals("sips"))
{
// MUST use TLS
forceTransport = "TLS";
logger.trace("detected SIPS URI, must use TLS");
}
else if(calleeURI.isSipURI() && calleeURI instanceof SipURI)
{
SipURI _calleeURI = (SipURI)calleeURI;
// check for a transport parameter
forceTransport = _calleeURI.getTransportParam();
if(forceTransport != null)
{
logger.trace("got transport parameter: " + forceTransport);
}
}
// Transaction
ClientTransaction inviteTransaction = null;
SipProvider jainSipProvider
= getProtocolProvider().getDefaultJainSipProvider();
SipProvider jainSipProvider;
if(forceTransport != null)
{
logger.trace("trying to use transport: " + forceTransport);
jainSipProvider = getProtocolProvider()
.getJainSipProvider(forceTransport);
}
else
{
logger.trace("trying default transport");
jainSipProvider = getProtocolProvider()
.getDefaultJainSipProvider();
}
try
{

@ -316,11 +316,15 @@ public void handleUri(String uri)
{
// make sure that we prompt for registration only if it is really
// required by the provider.
boolean handled = false;
if (exc.getErrorCode() == OperationFailedException.PROVIDER_NOT_REGISTERED)
{
promptForRegistration(uri, provider);
handled = promptForRegistration(uri, provider);
}
if(!handled)
{
showErrorMessage("Failed to create a call to " + uri, exc);
}
showErrorMessage("Failed to create a call to " + uri, exc);
}
catch (ParseException exc)
{
@ -335,8 +339,9 @@ public void handleUri(String uri)
*
* @param uri the uri that the user would like us to call after registering.
* @param provider the provider that we may have to reregister.
* @return true if user tried to start registration
*/
private void promptForRegistration(String uri,
private boolean promptForRegistration(String uri,
ProtocolProviderService provider)
{
int answer =
@ -351,7 +356,9 @@ private void promptForRegistration(String uri,
if (answer == PopupDialog.YES_OPTION)
{
new ProtocolRegistrationThread(uri, provider).start();
return true;
}
return false;
}
/**

@ -19,6 +19,7 @@
import net.java.sip.communicator.service.replacement.*;
import org.jitsi.service.configuration.*;
import org.jitsi.service.resources.*;
/**
* The <tt>ConfigurationForm</tt> that would be added in the chat configuration
@ -42,12 +43,17 @@ public class ReplacementConfigPanel
/**
* Checkbox to enable/disable replacements other than smileys.
*/
private JCheckBox enableReplacement;
private JRadioButton enableReplacement;
/**
* Checkbox to enable/disable proposal messages for image/video replacement.
*/
private JCheckBox enableReplacementProposal;
private JRadioButton enableReplacementProposal;
/**
* Checkbox to disable image/video replacement.
*/
private JRadioButton disableReplacement;
/**
* Jtable to list all the available replacement sources.
@ -77,16 +83,17 @@ public ReplacementConfigPanel()
*/
private Component createMainPanel()
{
JPanel mainPanel = new TransparentPanel(new BorderLayout());
JPanel mainPanel = new TransparentPanel();
mainPanel.setLayout(new BoxLayout(mainPanel, BoxLayout.Y_AXIS));
ResourceManagementService R = ChatConfigActivator.getResources();
enableSmiley =
new SIPCommCheckBox(ChatConfigActivator.getResources()
.getI18NString(
new SIPCommCheckBox(R.getI18NString(
"plugin.chatconfig.replacement.ENABLE_SMILEY_STATUS"));
mainPanel.add(enableSmiley, BorderLayout.WEST);
mainPanel.add(enableSmiley);
enableSmiley.addActionListener(new ActionListener()
{
@ -99,32 +106,34 @@ public void actionPerformed(ActionEvent e)
mainPanel.add(Box.createVerticalStrut(10));
JPanel replacementPanel = new TransparentPanel();
replacementPanel.setLayout(new BoxLayout(replacementPanel, BoxLayout.Y_AXIS));
replacementPanel.setBorder(
BorderFactory.createCompoundBorder(
BorderFactory.createTitledBorder(R.getI18NString(
"plugin.chatconfig.replacement.REPLACEMENT_TITLE")),
BorderFactory.createEmptyBorder(3, 3, 3, 3)));
enableReplacement =
new SIPCommCheckBox(ChatConfigActivator.getResources()
.getI18NString(
new SIPCommRadioButton(R.getI18NString(
"plugin.chatconfig.replacement.ENABLE_REPLACEMENT_STATUS"));
mainPanel.add(enableReplacement, BorderLayout.WEST);
replacementPanel.add(enableReplacement);
enableReplacement.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
saveData();
table.revalidate();
table.repaint();
}
});
mainPanel.add(Box.createVerticalStrut(10));
enableReplacementProposal =
new SIPCommCheckBox(ChatConfigActivator.getResources()
.getI18NString(
"plugin.chatconfig.replacement.ENABLE_REPLACEMENT_PROPOSAL"));
new SIPCommRadioButton(R.getI18NString(
"plugin.chatconfig.replacement.ENABLE_REPLACEMENT_PROPOSAL"
));
mainPanel.add(enableReplacementProposal, BorderLayout.WEST);
replacementPanel.add(enableReplacementProposal);
enableReplacementProposal.addActionListener(new ActionListener(){
@ -133,8 +142,25 @@ public void actionPerformed(ActionEvent arg0)
saveData();
}
});
disableReplacement = new SIPCommRadioButton(R.getI18NString(
"plugin.chatconfig.replacement.DISABLE_REPLACEMENT"));
replacementPanel.add(disableReplacement);
// the Jtable to list all the available sources
disableReplacement.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent arg0)
{
saveData();
}
});
ButtonGroup replacementGroup = new ButtonGroup();
replacementGroup.add(enableReplacement);
replacementGroup.add(enableReplacementProposal);
replacementGroup.add(disableReplacement);
// the JTable to list all the available sources
table = new JTable();
table.setShowGrid(false);
table.setTableHeader(null);
@ -144,18 +170,19 @@ public void actionPerformed(ActionEvent arg0)
JScrollPane tablePane = new JScrollPane(table);
tablePane.setOpaque(false);
tablePane.setPreferredSize(new Dimension(mainPanel.getWidth(), 150));
tablePane.setPreferredSize(
new Dimension(replacementPanel.getWidth(), 150));
tablePane.setAlignmentX(LEFT_ALIGNMENT);
JPanel container = new TransparentPanel(new BorderLayout());
container.setPreferredSize(new Dimension(mainPanel.getWidth(), 200));
container.setPreferredSize(
new Dimension(replacementPanel.getWidth(), 200));
container.setLayout(new BoxLayout(container, BoxLayout.Y_AXIS));
JLabel label =
new JLabel(ChatConfigActivator.getResources().getI18NString(
new JLabel(R.getI18NString(
"plugin.chatconfig.replacement.REPLACEMENT_SOURCES"));
label.setDisplayedMnemonic(ChatConfigActivator.getResources()
.getI18nMnemonic(
label.setDisplayedMnemonic(R.getI18nMnemonic(
"plugin.chatconfig.replacement.REPLACEMENT_SOURCES"));
label.setLabelFor(table);
@ -202,8 +229,10 @@ public void valueChanged(ListSelectionEvent e)
table.setDefaultRenderer(table.getColumnClass(1),
new FixedTableCellRenderer());
mainPanel.add(Box.createVerticalStrut(10));
mainPanel.add(container, BorderLayout.WEST);
replacementPanel.add(Box.createVerticalStrut(10));
replacementPanel.add(container);
mainPanel.add(replacementPanel);
return mainPanel;
}
@ -216,24 +245,25 @@ private void initValues()
ConfigurationService configService =
ChatConfigActivator.getConfigurationService();
boolean e =
configService.getBoolean(ReplacementProperty
.getPropertyName(ReplacementServiceSmileyImpl.SMILEY_SOURCE),
true);
this.enableSmiley.setSelected(e);
this.enableSmiley.setSelected(
configService.getBoolean(
ReplacementProperty.getPropertyName(
ReplacementServiceSmileyImpl.SMILEY_SOURCE),
true));
e =
configService.getBoolean(ReplacementProperty.REPLACEMENT_ENABLE,
true);
this.enableReplacement.setSelected(e);
this.enableReplacement.setSelected(
configService.getBoolean(
ReplacementProperty.REPLACEMENT_ENABLE, true));
this.enableReplacementProposal.setEnabled(!e);
e =
configService.getBoolean(ReplacementProperty.REPLACEMENT_PROPOSAL,
true);
this.enableReplacementProposal.setSelected(e);
this.enableReplacementProposal.setSelected(
configService.getBoolean(
ReplacementProperty.REPLACEMENT_PROPOSAL, true));
this.table.setEnabled(e);
this.disableReplacement.setSelected(
!this.enableReplacement.isSelected()
&& !this.enableReplacementProposal.isSelected());
this.table.setEnabled(enableReplacement.isSelected());
}
/**
@ -251,15 +281,13 @@ private void saveData()
configService.setProperty(ReplacementProperty.REPLACEMENT_ENABLE,
Boolean.toString(enableReplacement.isSelected()));
boolean e = enableReplacement.isSelected();
enableReplacementProposal.setEnabled(!e);
configService.setProperty(
"plugin.chatconfig.replacement.proposal.enable"
, Boolean.toString(!e && enableReplacementProposal.isSelected()));
"plugin.chatconfig.replacement.proposal.enable",
Boolean.toString(enableReplacementProposal.isSelected()));
table.getSelectionModel().clearSelection();
table.setEnabled(e);
table.setEnabled(enableReplacement.isSelected()
|| enableReplacementProposal.isSelected());
}
/**

@ -11,6 +11,7 @@
import java.security.cert.*;
import javax.swing.*;
import javax.swing.border.*;
import net.java.sip.communicator.service.certificate.*;
import net.java.sip.communicator.util.*;
@ -51,9 +52,9 @@ class VerifyCertificateDialogImpl
private static final int MAX_MSG_PANE_HEIGHT = 800;
/**
* The certificate to show.
* The certificates to show.
*/
Certificate cert;
Certificate[] certs;
/**
* A text that describes why the verification failed.
@ -110,8 +111,7 @@ public VerifyCertificateDialogImpl(Certificate[] certs,
R.getI18NString("service.gui.CERT_DIALOG_TITLE"));
setModal(true);
// for now shows only the first certificate from the chain
this.cert = certs[0];
this.certs = certs;
this.message = message;
setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
@ -224,34 +224,11 @@ private void actionShowCertificate()
return;
}
certPanel.setLayout(new BorderLayout());
certPanel.setLayout(new BorderLayout(5, 5));
certPanel.setBorder(new EmptyBorder(10, 10, 10, 10));
certPanel.add(alwaysTrustCheckBox, BorderLayout.NORTH);
Component certInfoPane = null;
if(cert instanceof X509Certificate)
{
certInfoPane = new X509CertificatePanel((X509Certificate)cert);
}
else
{
JTextArea textArea = new JTextArea();
textArea.setOpaque(false);
textArea.setEditable(false);
textArea.setText(cert.toString());
certInfoPane = textArea;
}
final JScrollPane certScroll = new JScrollPane(certInfoPane);
certScroll.setPreferredSize(new Dimension(300, 300));
certPanel.add(certScroll, BorderLayout.CENTER);
SwingUtilities.invokeLater(new Runnable()
{
public void run()
{
certScroll.getVerticalScrollBar().setValue(0);
}
});
certPanel.add(new X509CertificatePanel(certs), BorderLayout.CENTER);
certButton.setText(R.getI18NString("service.gui.HIDE_CERT"));

@ -39,9 +39,9 @@ public class ViewCertificateFrame
private static final int MAX_MSG_PANE_HEIGHT = 800;
/**
* The certificate to show.
* The certificates to show.
*/
Certificate cert;
Certificate[] certs;
/**
* A text that describes why the verification failed.
@ -74,8 +74,7 @@ public ViewCertificateFrame(Certificate[] certs,
setTitle(title != null ? title :
R.getI18NString("service.gui.CERT_DIALOG_TITLE"));
// for now shows only the first certificate from the chain
this.cert = certs[0];
this.certs = certs;
this.message = message;
setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
@ -123,31 +122,8 @@ private void init()
this.getContentPane().add(contentPane, BorderLayout.CENTER);
Component certInfoPane;
if(cert instanceof X509Certificate)
{
certInfoPane = new X509CertificatePanel((X509Certificate)cert);
}
else
{
JTextArea textArea = new JTextArea();
textArea.setOpaque(false);
textArea.setEditable(false);
textArea.setText(cert.toString());
certInfoPane = textArea;
}
final JScrollPane certScroll = new JScrollPane(certInfoPane);
certScroll.setPreferredSize(new Dimension(300, 600));
certPanel.add(certScroll, BorderLayout.CENTER);
SwingUtilities.invokeLater(new Runnable()
{
public void run()
{
certScroll.getVerticalScrollBar().setValue(0);
}
});
certPanel.add(new X509CertificatePanel(certs), BorderLayout.CENTER);
setPreferredSize(null);
pack();

@ -9,14 +9,18 @@
import java.awt.*;
import java.security.*;
import java.security.cert.*;
import java.security.cert.Certificate;
import java.security.interfaces.*;
import java.text.*;
import java.util.*;
import javax.naming.*;
import javax.naming.ldap.*;
import javax.security.auth.x500.*;
import javax.swing.*;
import javax.swing.border.*;
import javax.swing.event.*;
import javax.swing.text.*;
import javax.swing.tree.*;
import org.jitsi.service.resources.*;
@ -28,42 +32,171 @@ public class X509CertificatePanel
{
private static final long serialVersionUID = -8368302061995971947L;
private final JEditorPane infoTextPane = new JEditorPane();
private final ResourceManagementService R
= DesktopUtilActivator.getResources();
/**
* Constructs a X509 certificate panel.
* Constructs a X509 certificate panel from a single certificate.
* If a chain is available instead use the second constructor.
* This constructor is kept for backwards compatibility and for convenience
* when there is only one certificate of interest.
*
* @param certificate <tt>X509Certificate</tt> object
*/
public X509CertificatePanel(X509Certificate certificate)
public X509CertificatePanel(Certificate certificate)
{
this(new Certificate[]
{
certificate
});
}
/**
* Constructs a X509 certificate panel.
*
* @param certificates <tt>X509Certificate</tt> objects
*/
public X509CertificatePanel(Certificate[] certificates)
{
ResourceManagementService R = DesktopUtilActivator.getResources();
DateFormat dateFormatter
= DateFormat.getDateInstance(DateFormat.MEDIUM);
setLayout(new BorderLayout(5, 5));
// Certificate chain list
TransparentPanel topPanel = new TransparentPanel(new BorderLayout());
topPanel.add(new JLabel("<html><body><b>"
+ R.getI18NString("service.gui.CERT_INFO_CHAIN")
+ "</b></body></html>"), BorderLayout.NORTH);
DefaultMutableTreeNode top = new DefaultMutableTreeNode();
DefaultMutableTreeNode previous = top;
for (int i = certificates.length - 1; i >= 0; i--)
{
Certificate cert = certificates[i];
DefaultMutableTreeNode next = new DefaultMutableTreeNode(cert);
previous.add(next);
previous = next;
}
JTree tree = new JTree(top);
tree.setBorder(new BevelBorder(BevelBorder.LOWERED));
tree.setRootVisible(false);
tree.setExpandsSelectedPaths(true);
tree.getSelectionModel().setSelectionMode(
TreeSelectionModel.SINGLE_TREE_SELECTION);
tree.setCellRenderer(new DefaultTreeCellRenderer()
{
@Override
public Component getTreeCellRendererComponent(JTree tree,
Object value, boolean sel, boolean expanded, boolean leaf,
int row, boolean hasFocus)
{
JLabel component = (JLabel) super.getTreeCellRendererComponent(
tree, value, sel, expanded, leaf, row, hasFocus);
if (value instanceof DefaultMutableTreeNode)
{
Object o = ((DefaultMutableTreeNode) value).getUserObject();
if (o instanceof X509Certificate)
{
component.setText(
getSimplifiedName((X509Certificate) o));
}
else
{
// We don't know how to represent this certificate type,
// let's use the first 20 characters
String text = o.toString();
if (text.length() > 20)
{
text = text.substring(0, 20);
}
component.setText(text);
}
}
return component;
}
});
tree.getSelectionModel().addTreeSelectionListener(
new TreeSelectionListener()
{
@Override
public void valueChanged(TreeSelectionEvent e)
{
valueChangedPerformed(e);
}
});
tree.setSelectionPath(new TreePath(((
(DefaultTreeModel)tree.getModel()).getPathToRoot(previous))));
topPanel.add(tree, BorderLayout.CENTER);
add(topPanel, BorderLayout.NORTH);
// Certificate details pane
Caret caret = infoTextPane.getCaret();
if (caret instanceof DefaultCaret)
{
((DefaultCaret) caret).setUpdatePolicy(DefaultCaret.NEVER_UPDATE);
}
Insets valueInsets = new Insets(2,10,0,0);
Insets titleInsets = new Insets(10,5,0,0);
/*
* Make JEditorPane respect our default font because we will be using it
* to just display text.
*/
infoTextPane.putClientProperty(
JEditorPane.HONOR_DISPLAY_PROPERTIES,
true);
infoTextPane.setOpaque(false);
infoTextPane.setEditable(false);
infoTextPane.setContentType("text/html");
infoTextPane.setText(toString(certificates[0]));
final JScrollPane certScroll = new JScrollPane(infoTextPane);
certScroll.setPreferredSize(new Dimension(300, 500));
add(certScroll, BorderLayout.CENTER);
}
setLayout(new GridBagLayout());
/**
* Creates a String representation of the given object.
* @param certificate to print
* @return the String representation
*/
private String toString(Object certificate)
{
final StringBuilder sb = new StringBuilder();
sb.append("<html><body>\n");
int currentRow = 0;
if (certificate instanceof X509Certificate)
{
renderX509(sb, (X509Certificate) certificate);
}
else
{
sb.append("<pre>\n");
sb.append(certificate.toString());
sb.append("</pre>\n");
}
GridBagConstraints constraints = new GridBagConstraints();
constraints.anchor = GridBagConstraints.WEST;
constraints.fill = GridBagConstraints.HORIZONTAL;
constraints.insets = new Insets(2,5,0,0);
constraints.gridx = 0;
constraints.weightx = 0;
constraints.weighty = 0;
constraints.gridy = currentRow++;
sb.append("</body></html>");
return sb.toString();
}
/**
* Appends an HTML representation of the given X509Certificate.
* @param sb StringBuilder to append to
* @param certificate to print
*/
private void renderX509(StringBuilder sb, X509Certificate certificate)
{
X500Principal issuer = certificate.getIssuerX500Principal();
X500Principal subject = certificate.getSubjectX500Principal();
add(new JLabel(
R.getI18NString("service.gui.CERT_INFO_ISSUED_TO")),
constraints);
sb.append("<table cellspacing='1' cellpadding='1'>\n");
// subject
constraints.insets = valueInsets;
addTitle(sb, R.getI18NString("service.gui.CERT_INFO_ISSUED_TO"));
try
{
for(Rdn name : new LdapName(subject.getName()).getRdns())
@ -75,47 +208,31 @@ public X509CertificatePanel(X509Certificate certificate)
if ((lbl == null) || ("!" + lblKey + "!").equals(lbl))
lbl = nameType;
constraints.gridy = currentRow++;
constraints.gridx = 0;
add(new JLabel(lbl), constraints);
final String value;
Object nameValue = name.getValue();
if (nameValue instanceof byte[])
{
byte[] nameValueAsByteArray = (byte[]) nameValue;
lbl
value
= getHex(nameValueAsByteArray) + " ("
+ new String(nameValueAsByteArray) + ")";
}
else
lbl = nameValue.toString();
value = nameValue.toString();
constraints.gridx = 1;
add(new JLabel(lbl), constraints);
addField(sb, lbl, value);
}
}
catch (InvalidNameException ine)
{
constraints.gridy = currentRow++;
add(new JLabel(
R.getI18NString("service.gui.CERT_INFO_CN")),
constraints);
constraints.gridx = 1;
add(
new JLabel(subject.getName()),
constraints);
addField(sb, R.getI18NString("service.gui.CERT_INFO_CN"),
subject.getName());
}
// issuer
constraints.gridy = currentRow++;
constraints.gridx = 0;
constraints.insets = titleInsets;
add(new JLabel(
R.getI18NString("service.gui.CERT_INFO_ISSUED_BY")),
constraints);
constraints.insets = valueInsets;
addTitle(sb, R.getI18NString("service.gui.CERT_INFO_ISSUED_BY"));
try
{
for(Rdn name : new LdapName(issuer.getName()).getRdns())
@ -127,268 +244,133 @@ public X509CertificatePanel(X509Certificate certificate)
if ((lbl == null) || ("!" + lblKey + "!").equals(lbl))
lbl = nameType;
constraints.gridy = currentRow++;
constraints.gridx = 0;
constraints.gridx = 0;
add(new JLabel(lbl), constraints);
final String value;
Object nameValue = name.getValue();
if (nameValue instanceof byte[])
{
byte[] nameValueAsByteArray = (byte[]) nameValue;
lbl
value
= getHex(nameValueAsByteArray) + " ("
+ new String(nameValueAsByteArray) + ")";
}
else
lbl = nameValue.toString();
value = nameValue.toString();
constraints.gridx = 1;
add(new JLabel(lbl), constraints);
addField(sb, lbl, value);
}
}
catch (InvalidNameException ine)
{
constraints.gridy = currentRow++;
add(new JLabel(
R.getI18NString("service.gui.CERT_INFO_CN")),
constraints);
constraints.gridx = 1;
add(
new JLabel(issuer.getName()),
constraints);
addField(sb, R.getI18NString("service.gui.CERT_INFO_CN"),
issuer.getName());
}
// validity
constraints.gridy = currentRow++;
constraints.gridx = 0;
constraints.insets = titleInsets;
add(new JLabel(
R.getI18NString("service.gui.CERT_INFO_VALIDITY")),
constraints);
constraints.insets = valueInsets;
constraints.gridy = currentRow++;
constraints.gridx = 0;
add(new JLabel(
R.getI18NString("service.gui.CERT_INFO_ISSUED_ON")),
constraints);
constraints.gridx = 1;
add(
new JLabel(dateFormatter.format(certificate.getNotBefore())),
constraints);
constraints.gridy = currentRow++;
constraints.gridx = 0;
add(new JLabel(
R.getI18NString("service.gui.CERT_INFO_EXPIRES_ON")),
constraints);
constraints.gridx = 1;
add(
new JLabel(dateFormatter.format(certificate.getNotAfter())),
constraints);
constraints.gridy = currentRow++;
constraints.gridx = 0;
constraints.insets = titleInsets;
add(new JLabel(
R.getI18NString("service.gui.CERT_INFO_FINGERPRINTS")),
constraints);
constraints.insets = valueInsets;
addTitle(sb, R.getI18NString("service.gui.CERT_INFO_VALIDITY"));
addField(sb, R.getI18NString("service.gui.CERT_INFO_ISSUED_ON"),
certificate.getNotBefore().toString());
addField(sb, R.getI18NString("service.gui.CERT_INFO_EXPIRES_ON"),
certificate.getNotAfter().toString());
addTitle(sb, R.getI18NString("service.gui.CERT_INFO_FINGERPRINTS"));
try
{
String sha1String = getThumbprint(certificate, "SHA1");
String md5String = getThumbprint(certificate, "MD5");
JTextArea sha1Area = new JTextArea(sha1String);
sha1Area.setLineWrap(false);
sha1Area.setOpaque(false);
sha1Area.setWrapStyleWord(true);
sha1Area.setEditable(false);
constraints.gridy = currentRow++;
constraints.gridx = 0;
add(new JLabel("SHA1:"),
constraints);
constraints.gridx = 1;
add(
sha1Area,
constraints);
constraints.gridy = currentRow++;
constraints.gridx = 0;
add(new JLabel("MD5:"),
constraints);
JTextArea md5Area = new JTextArea(md5String);
md5Area.setLineWrap(false);
md5Area.setOpaque(false);
md5Area.setWrapStyleWord(true);
md5Area.setEditable(false);
constraints.gridx = 1;
add(
md5Area,
constraints);
addField(sb, "SHA1:", sha1String);
addField(sb, "MD5:", md5String);
}
catch (Exception e)
catch (CertificateException e)
{
// do nothing as we cannot show this value
}
constraints.gridy = currentRow++;
constraints.gridx = 0;
constraints.insets = titleInsets;
add(new JLabel(
R.getI18NString("service.gui.CERT_INFO_CERT_DETAILS")),
constraints);
constraints.insets = valueInsets;
constraints.gridy = currentRow++;
constraints.gridx = 0;
add(new JLabel(
R.getI18NString("service.gui.CERT_INFO_SER_NUM")),
constraints);
constraints.gridx = 1;
add(
new JLabel(certificate.getSerialNumber().toString()),
constraints);
constraints.gridy = currentRow++;
constraints.gridx = 0;
add(new JLabel(
R.getI18NString("service.gui.CERT_INFO_VER")),
constraints);
constraints.gridx = 1;
add(
new JLabel(String.valueOf(certificate.getVersion())),
constraints);
constraints.gridy = currentRow++;
constraints.gridx = 0;
add(new JLabel(
R.getI18NString("service.gui.CERT_INFO_SIGN_ALG")),
constraints);
constraints.gridx = 1;
add(
new JLabel(String.valueOf(certificate.getSigAlgName())),
constraints);
constraints.gridy = currentRow++;
constraints.gridx = 0;
constraints.insets = titleInsets;
add(new JLabel(
R.getI18NString("service.gui.CERT_INFO_PUB_KEY_INFO")),
constraints);
constraints.insets = valueInsets;
constraints.gridy = currentRow++;
constraints.gridx = 0;
add(new JLabel(
R.getI18NString("service.gui.CERT_INFO_ALG")),
constraints);
constraints.gridx = 1;
add(
new JLabel(certificate.getPublicKey().getAlgorithm()),
constraints);
addTitle(sb, R.getI18NString("service.gui.CERT_INFO_CERT_DETAILS"));
addField(sb, R.getI18NString("service.gui.CERT_INFO_SER_NUM"),
certificate.getSerialNumber().toString());
addField(sb, R.getI18NString("service.gui.CERT_INFO_VER"),
String.valueOf(certificate.getVersion()));
addField(sb, R.getI18NString("service.gui.CERT_INFO_SIGN_ALG"),
String.valueOf(certificate.getSigAlgName()));
addTitle(sb, R.getI18NString("service.gui.CERT_INFO_PUB_KEY_INFO"));
addField(sb, R.getI18NString("service.gui.CERT_INFO_ALG"),
certificate.getPublicKey().getAlgorithm());
if(certificate.getPublicKey().getAlgorithm().equals("RSA"))
{
RSAPublicKey key = (RSAPublicKey)certificate.getPublicKey();
constraints.gridy = currentRow++;
constraints.gridx = 0;
add(new JLabel(
R.getI18NString("service.gui.CERT_INFO_PUB_KEY")),
constraints);
JTextArea pubkeyArea = new JTextArea(
addField(sb, R.getI18NString("service.gui.CERT_INFO_PUB_KEY"),
R.getI18NString(
"service.gui.CERT_INFO_KEY_BYTES_PRINT",
new String[]{
String.valueOf(key.getModulus().toByteArray().length-1),
key.getModulus().toString(16)
}));
pubkeyArea.setLineWrap(false);
pubkeyArea.setOpaque(false);
pubkeyArea.setWrapStyleWord(true);
pubkeyArea.setEditable(false);
constraints.gridx = 1;
add(
pubkeyArea,
constraints);
constraints.gridy = currentRow++;
constraints.gridx = 0;
add(new JLabel(
R.getI18NString("service.gui.CERT_INFO_EXP")),
constraints);
constraints.gridx = 1;
add(
new JLabel(key.getPublicExponent().toString()),
constraints);
constraints.gridy = currentRow++;
constraints.gridx = 0;
add(new JLabel(
R.getI18NString("service.gui.CERT_INFO_KEY_SIZE")),
constraints);
constraints.gridx = 1;
add(
new JLabel(R.getI18NString(
addField(sb, R.getI18NString("service.gui.CERT_INFO_EXP"),
key.getPublicExponent().toString());
addField(sb, R.getI18NString("service.gui.CERT_INFO_KEY_SIZE"),
R.getI18NString(
"service.gui.CERT_INFO_KEY_BITS_PRINT",
new String[]{
String.valueOf(key.getModulus().bitLength())})),
constraints);
String.valueOf(key.getModulus().bitLength())}));
}
else if(certificate.getPublicKey().getAlgorithm().equals("DSA"))
{
DSAPublicKey key =
(DSAPublicKey)certificate.getPublicKey();
constraints.gridy = currentRow++;
constraints.gridx = 0;
add(new JLabel("Y:"), constraints);
JTextArea yArea = new JTextArea(key.getY().toString(16));
yArea.setLineWrap(false);
yArea.setOpaque(false);
yArea.setWrapStyleWord(true);
yArea.setEditable(false);
constraints.gridx = 1;
add(
yArea,
constraints);
addField(sb, "Y:", key.getY().toString(16));
}
constraints.gridy = currentRow++;
constraints.gridx = 0;
add(new JLabel(
R.getI18NString("service.gui.CERT_INFO_SIGN")),
constraints);
JTextArea signArea = new JTextArea(
addField(sb, R.getI18NString("service.gui.CERT_INFO_SIGN"),
R.getI18NString(
"service.gui.CERT_INFO_KEY_BYTES_PRINT",
new String[]{
String.valueOf(certificate.getSignature().length),
getHex(certificate.getSignature())
}));
signArea.setLineWrap(false);
signArea.setOpaque(false);
signArea.setWrapStyleWord(true);
signArea.setEditable(false);
constraints.gridx = 1;
add(
signArea,
constraints);
sb.append("</table>\n");
}
/**
* Add a title.
*
* @param sb StringBuilder to append to
* @param title to print
*/
private void addTitle(StringBuilder sb, String title)
{
sb.append("<tr><td colspan='2'")
.append(" style='margin-top: 5pt; white-space: nowrap'><p><b>")
.append(title).append("</b></p></td></tr>\n");
}
/**
* Add a field.
* @param sb StringBuilder to append to
* @param field name of the certificate field
* @param value to print
*/
private void addField(StringBuilder sb, String field, String value)
{
sb.append("<tr>")
.append("<td style='margin-left: 5pt; margin-right: 25pt;")
.append(" white-space: nowrap'>")
.append(field).append("</td>")
.append("<td>").append(value).append("</td>")
.append("</tr>\n");
}
/**
@ -450,4 +432,62 @@ private static String getThumbprint(X509Certificate cert, String algorithm)
}
return sb.toString();
}
/**
* Construct a "simplified name" based on the subject DN from the
* certificate. The purpose is to have something shorter to display in the
* list. The name used is one of the following DN parts, if
* available, otherwise the complete DN:
* 'CN', 'OU' or else 'O'.
* @param cert to read subject DN from
* @return the simplified name
*/
private static String getSimplifiedName(X509Certificate cert)
{
final HashMap<String, String> parts = new HashMap<String, String>();
try
{
for (Rdn name : new LdapName(
cert.getSubjectX500Principal().getName()).getRdns())
{
if (name.getType() != null && name.getValue() != null)
{
parts.put(name.getType(), name.getValue().toString());
}
}
}
catch (InvalidNameException ignored) // NOPMD
{
}
String result = parts.get("CN");
if (result == null)
{
result = parts.get("OU");
}
if (result == null)
{
result = parts.get("O");
}
if (result == null)
{
result = cert.getSubjectX500Principal().getName();
}
return result;
}
/**
* Called when the selection changed in the tree.
* Loads the selected certificate.
* @param e the event
*/
private void valueChangedPerformed(TreeSelectionEvent e)
{
Object o = e.getNewLeadSelectionPath().getLastPathComponent();
if (o instanceof DefaultMutableTreeNode)
{
DefaultMutableTreeNode node = (DefaultMutableTreeNode) o;
infoTextPane.setText(toString(node.getUserObject()));
}
}
}

Loading…
Cancel
Save