summaryrefslogtreecommitdiffstats
Unidiff
Diffstat (more/less context) (ignore whitespace changes)
-rw-r--r--changelog.html55
-rw-r--r--plugin.xml19
-rw-r--r--readme.html75
-rw-r--r--src/i18n/vcardextpres_i18n.properties17
-rw-r--r--src/i18n/vcardextpres_i18n_nl.properties17
-rw-r--r--src/java/org/jivesoftware/wildfire/plugin/VCardExtendedPresencePlugin.java315
-rw-r--r--src/web/images/success-16x16.gifbin0 -> 1016 bytes
-rw-r--r--src/web/vcardextpres.jsp130
8 files changed, 628 insertions, 0 deletions
diff --git a/changelog.html b/changelog.html
new file mode 100644
index 0000000..7c7761f
--- a/dev/null
+++ b/changelog.html
@@ -0,0 +1,55 @@
1<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
2
3<html>
4<head>
5 <title>vCard-based Extended Presence Plugin Changelog</title>
6 <style type="text/css">
7 BODY {
8 font-size : 100%;
9 }
10 BODY, TD, TH {
11 font-family : tahoma, verdana, arial, helvetica, sans-serif;
12 font-size : 0.8em;
13 }
14 H2 {
15 font-size : 10pt;
16 font-weight : bold;
17 padding-left : 1em;
18 }
19 A:hover {
20 text-decoration : none;
21 }
22 H1 {
23 font-family : tahoma, arial, helvetica, sans-serif;
24 font-size : 1.4em;
25 font-weight: bold;
26 border-bottom : 1px #ccc solid;
27 padding-bottom : 2px;
28 }
29
30 TT {
31 font-family : courier new;
32 font-weight : bold;
33 color : #060;
34 }
35 PRE {
36 font-family : courier new;
37 font-size : 100%;
38 }
39 </style>
40</head>
41<body>
42
43<h1>
44vCard-based Extended Presence Plugin Changelog
45</h1>
46
47<p><b>0.1</b> -- July 13, 2006</p>
48
49<ul>
50 <li>Initial release. </li>
51</ul>
52
53
54</body>
55</html>
diff --git a/plugin.xml b/plugin.xml
new file mode 100644
index 0000000..bb4b90e
--- a/dev/null
+++ b/plugin.xml
@@ -0,0 +1,19 @@
1<?xml version="1.0" encoding="UTF-8"?>
2
3<plugin>
4 <class>org.jivesoftware.wildfire.plugin.VCardExtendedPresencePlugin</class>
5 <name>${vcardextpres.name}</name>
6 <description>${vcardextpres.description}</description>
7 <author>Remko Tron&#231;on</author>
8 <version>0.1</version>
9 <date>7/13/2006</date>
10 <minServerVersion>3.0.1</minServerVersion>
11
12 <adminconsole>
13 <tab id="tab-server">
14 <sidebar id="sidebar-server-settings">
15 <item id="vcardextpres" name="${vcardextpres.name}" url="vcardextpres.jsp" description="${vcardextpres.sidebar.instructions}" />
16 </sidebar>
17 </tab>
18 </adminconsole>
19</plugin>
diff --git a/readme.html b/readme.html
new file mode 100644
index 0000000..141f0eb
--- a/dev/null
+++ b/readme.html
@@ -0,0 +1,75 @@
1<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
2
3<html>
4<head>
5 <title>vCard-based Extended Presence Plugin Readme</title>
6 <style type="text/css">
7 BODY {
8 font-size : 100%;
9 }
10 BODY, TD, TH {
11 font-family : tahoma, verdana, arial, helvetica, sans-serif;
12 font-size : 0.8em;
13 }
14 H2 {
15 font-size : 10pt;
16 font-weight : bold;
17 }
18 A:hover {
19 text-decoration : none;
20 }
21 H1 {
22 font-family : tahoma, arial, helvetica, sans-serif;
23 font-size : 1.4em;
24 font-weight: bold;
25 border-bottom : 1px #ccc solid;
26 padding-bottom : 2px;
27 }
28
29 TT {
30 font-family : courier new;
31 font-weight : bold;
32 color : #060;
33 }
34 PRE {
35 font-family : courier new;
36 font-size : 100%;
37 }
38 </style>
39</head>
40<body>
41
42<h1>
43vCard-based Extended Presence Plugin Readme
44</h1>
45
46<h2>Overview</h2>
47<p>
48The vCard-based Extended Presence Plugin automatically annotates presence
49packets and message packets to unsubscribed users with extended presence
50information about the user. Currently, it supports sending of avatar
51(<a href="http://www.jabber.org/jeps/jep-0153.html">JEP-0153</a>)
52and nickname (<a href="http://www.jabber.org/jeps/jep-0172.html">JEP-0172</a>)
53information.
54</p>
55
56<h2>Installation</h2>
57<p>
58Copy <tt>vcardextpres.jar</tt> into the plugins directory of your Wildfire
59installation. The plugin will then be automatically deployed. To upgrade to a
60new version, copy the new <tt>vcardextpres.jar</tt> file over the existing file.
61</p>
62
63<h2>Configuration</h2>
64<p>
65All the extended presence settings can be changed from the 'vCard-based
66Extended Presence' page in the Wildfire admin console.
67</p>
68
69<h2>Using the Plugin</h2>
70<p>
71The plugin is automatically activated.
72</p>
73
74</body>
75</html>
diff --git a/src/i18n/vcardextpres_i18n.properties b/src/i18n/vcardextpres_i18n.properties
new file mode 100644
index 0000000..28b3b8c
--- a/dev/null
+++ b/src/i18n/vcardextpres_i18n.properties
@@ -0,0 +1,17 @@
1login.title=Admin Console
2vcardextpres.name=vCard-based Extended Presence
3vcardextpres.description=Annotates packets with information from the vCard.
4vcardextpres.sidebar.instructions=Click to manage the service that adds vCard-based extended presence
5vcardextpres.config.title=vCard-based Extended Presence Properties
6vcardextpres.config.instructions=Use the form below to configure vCard-based extended presence.
7vcardextpres.config.success=vCard-based Extended Presence properties edited successfully.
8vcardextpres.config.avatars.title=Avatars
9vcardextpres.config.avatars.description=This option adds information about the photo in the vcard to all presence packets. Using this information, clients supporting vCard-based avatars can detect photo updates and fetch the new vCard accordingly.
10vcardextpres.config.avatars.enabled=Avatar information will be added to presence packets
11vcardextpres.config.avatars.disabled=Avatar information will not be added to presence packets
12vcardextpres.config.nick.title=Nicknames
13vcardextpres.config.nick.description=This option adds information about the nickname of the user to authorization requests and messages to contacts that do not have a subscription to your presence.
14vcardextpres.config.nick.enabled=Nickname information will be added to packets
15vcardextpres.config.nick.disabled=Nickname information will not be added to packets
16vcardextpres.enabled=Enabled
17vcardextpres.disabled=Disabled
diff --git a/src/i18n/vcardextpres_i18n_nl.properties b/src/i18n/vcardextpres_i18n_nl.properties
new file mode 100644
index 0000000..033b81d
--- a/dev/null
+++ b/src/i18n/vcardextpres_i18n_nl.properties
@@ -0,0 +1,17 @@
1login.title=Beheerdersconsole
2vcardextpres.name=vCard-gebaseerde uitgebreide status
3vcardextpres.description=Annoteert status pakketten met informatie uit de vCard
4vcardextpres.sidebar.instructions=Klik hier om de component te beheren die vCard-gebaseerde uitgebreide statusinformatie toevoegt
5vcardextpres.config.title=vCard-gebaseerde uitgebreide status eigenschappen
6vcardextpres.config.instructions=Gebruik onderstaand formulier om de vCard-gebaseerde uitgebreide status te configureren.
7vcardextpres.config.success=vCard-gebaseerde uitgebreide status eigenschappen succesvol aangepast
8vcardextpres.config.avatars.title=Avatars
9vcardextpres.config.avatars.description=Deze optie voegt informatie over de foto uit de vCard aan alle status pakketten toe. Door middel van deze informatie kunnen clients die het vCard-gebaseerde avatar protocol ondersteunen detecteren wanneer een foto aangepast is, en zo de nieuwe versie opvragen.
10vcardextpres.config.avatars.enabled=Avatar informatie zal toegevoegd worden aan status pakketten
11vcardextpres.config.avatars.disabled=Avatar informatie zal niet toegevoegd worden aan status pakketten
12vcardextpres.config.nick.title=Roepnamen
13vcardextpres.config.nick.description=Deze optie voegt informatie over de roepnaam van een gebruiker toe aan pakketten die bestemd zijn voor contacten die de gebruiker niet op hun contactenlijst staan hebben.
14vcardextpres.config.nick.enabled=Roepnaam informatie zal toegevoegd worden aan pakketten
15vcardextpres.config.nick.disabled=Roepnaam informatie zal niet toegevoegd worden aan pakketten
16vcardextpres.enabled=Actief
17vcardextpres.disabled=Inactief
diff --git a/src/java/org/jivesoftware/wildfire/plugin/VCardExtendedPresencePlugin.java b/src/java/org/jivesoftware/wildfire/plugin/VCardExtendedPresencePlugin.java
new file mode 100644
index 0000000..76d0b81
--- a/dev/null
+++ b/src/java/org/jivesoftware/wildfire/plugin/VCardExtendedPresencePlugin.java
@@ -0,0 +1,315 @@
1/**
2 * Copyright (C) 2006 Remko Troncon.
3 *
4 * This software is published under the terms of the GNU Public License (GPL),
5 * a copy of which is included in this distribution.
6 */
7
8package org.jivesoftware.wildfire.plugin;
9
10import org.dom4j.Element;
11import org.dom4j.QName;
12import org.dom4j.Namespace;
13
14import org.jivesoftware.util.StringUtils;
15import org.jivesoftware.util.JiveGlobals;
16import org.jivesoftware.util.PropertyEventListener;
17import org.jivesoftware.util.PropertyEventDispatcher;
18import org.jivesoftware.wildfire.Session;
19import org.jivesoftware.wildfire.PresenceManager;
20import org.jivesoftware.wildfire.PresenceRouter;
21import org.jivesoftware.wildfire.XMPPServer;
22import org.jivesoftware.wildfire.container.Plugin;
23import org.jivesoftware.wildfire.container.PluginManager;
24import org.jivesoftware.wildfire.interceptor.InterceptorManager;
25import org.jivesoftware.wildfire.interceptor.PacketInterceptor;
26import org.jivesoftware.wildfire.interceptor.PacketRejectedException;
27import org.jivesoftware.wildfire.roster.Roster;
28import org.jivesoftware.wildfire.roster.RosterManager;
29import org.jivesoftware.wildfire.roster.RosterItem;
30import org.jivesoftware.wildfire.user.UserManager;
31import org.jivesoftware.wildfire.user.UserNotFoundException;
32import org.jivesoftware.wildfire.vcard.VCardManager;
33import org.jivesoftware.wildfire.vcard.VCardListener;
34
35import org.xmpp.packet.Message;
36import org.xmpp.packet.Presence;
37import org.xmpp.packet.Presence.Type;
38import org.xmpp.packet.Packet;
39import org.xmpp.packet.JID;
40
41import java.io.File;
42import java.util.HashMap;
43import java.util.Iterator;
44import java.util.Map;
45
46/**
47 * vCard-based Extended Presence plugin.
48 *
49 * This plugin annotates packets with information from the vCard.
50 * It adds the hash of the PHOTO field of a user's vCard to all its
51 * outgoing presence packets, according to <a href="http://www.jabber.org/jeps/jep-0153.html">JEP-0153 (vCard-based avatars)</a>.
52 *
53 * For messages and subscription requests to contacts that do not have a
54 * user on their roster, it adds the user's nickname according to <a href="ttp://www.jabber.org/jeps/jep-0172.html">JEP-0172 (User Nickname)</a>.
55 *
56 * If the message or presence packet already contains extended presence
57 * information, the plugin does not overwrite it.
58 *
59 * @author Remko Tron&ccedil;on
60 */
61public class VCardExtendedPresencePlugin implements Plugin, PacketInterceptor, VCardListener, PropertyEventListener {
62 private XMPPServer xmppServer;
63 private UserManager userManager;
64 private InterceptorManager interceptorManager;
65 private VCardManager vcardManager;
66 private RosterManager rosterManager;
67 private PresenceManager presenceManager;
68 private PresenceRouter presenceRouter;
69 private boolean nickEnabled;
70 private boolean photoHashEnabled;
71
72 private HashMap<String,String> nicks = new HashMap();
73 private HashMap<String,String> photoHashes = new HashMap();
74
75 public VCardExtendedPresencePlugin() {
76 xmppServer = XMPPServer.getInstance();
77 interceptorManager = InterceptorManager.getInstance();
78 vcardManager = VCardManager.getInstance();
79 rosterManager = xmppServer.getRosterManager();
80 userManager = xmppServer.getUserManager();
81 presenceManager = xmppServer.getPresenceManager();
82 presenceRouter = xmppServer.getPresenceRouter();
83 }
84
85 public void initializePlugin(PluginManager pm, File f) {
86 nickEnabled = JiveGlobals.getBooleanProperty("plugin.vcardextpres.nickEnabled", false);
87 photoHashEnabled = JiveGlobals.getBooleanProperty("plugin.vcardextpres.photoHashEnabled", false);
88 interceptorManager.addInterceptor(this);
89 vcardManager.addListener(this);
90 PropertyEventDispatcher.addListener(this);
91 }
92
93 public void destroyPlugin() {
94 vcardManager.removeListener(this);
95 interceptorManager.removeInterceptor(this);
96 PropertyEventDispatcher.removeListener(this);
97 }
98
99 public void interceptPacket(Packet packet, Session session, boolean incoming, boolean processed) throws PacketRejectedException {
100 if (incoming || processed)
101 return;
102
103 // Check if the sender is a local, non-anonymous user
104 JID senderJID = packet.getFrom();
105 if (senderJID == null || !xmppServer.isLocal(senderJID))
106 return;
107 String user = senderJID.getNode();
108 if (!userManager.isRegisteredUser(user))
109 return;
110
111 if (packet instanceof Presence) {
112 Presence presence = (Presence) packet;
113
114 // Unavailable packets don't get extended presence information
115 if (presence.getType() == Presence.Type.unavailable)
116 return;
117
118 // Add photo hash if necessary
119 if (isPhotoHashEnabled()) {
120 addPhotoHash(presence,user);
121 }
122
123 // Nickname
124 if (presence.getType() == Presence.Type.subscribe && isNickEnabled()) {
125 addNick(presence,user);
126 }
127 }
128 else if (isNickEnabled() && packet instanceof Message) {
129 Message message = (Message) packet;
130
131 // Body-less messages don't get nicknames
132 if (message.getBody() == null)
133 return;
134
135 JID recipientJID = message.getTo();
136 if (recipientJID == null)
137 return;
138
139 if (message.getBody() != null) {
140 // Add a nickname if sender is not on recipient's roster
141 try {
142 Roster roster = rosterManager.getRoster(user);
143 RosterItem rosterItem = roster.getRosterItem(recipientJID);
144 if (rosterItem == null) {
145 addNick(message,user);
146 }
147 else {
148 RosterItem.SubType type = rosterItem.getSubStatus();
149 if (type != RosterItem.SUB_BOTH && type != RosterItem.SUB_FROM) {
150 addNick(message,user);
151 }
152 }
153 }
154 catch (UserNotFoundException e) { }
155 }
156 }
157 }
158
159 /**
160 * Checks whether nickname information should be added to packets.
161 */
162 public boolean isNickEnabled() {
163 return nickEnabled;
164 }
165
166 /**
167 * Enables or disables adding of nickname information to packets.
168 */
169 public void setNickEnabled(boolean b) {
170 JiveGlobals.setProperty("plugin.vcardextpres.nickEnabled", ( b ? "true" : "false"));
171 }
172
173 /**
174 * Checks whether photo hash information should be added to packets.
175 */
176 public boolean isPhotoHashEnabled() {
177 return photoHashEnabled;
178 }
179
180 /**
181 * Enables or disables adding of photo hash information to packets.
182 */
183 public void setPhotoHashEnabled(boolean b) {
184 JiveGlobals.setProperty("plugin.vcardextpres.photoHashEnabled", ( b ? "true" : "false"));
185 }
186
187 /**
188 * Retrieves the nickname from the user's vCard NICK field.
189 * This information is cached.
190 *
191 * @param user the user whose information is fetched
192 * @param force do not use cached information
193 * @return the user's nickname
194 */
195 protected String getNick(String user, boolean force) {
196 if (!nicks.containsKey(user) || force) {
197 String nick = vcardManager.getVCardProperty(user,"NICKNAME");
198 if (nick != null && nick.length() > 0) {
199 nicks.put(user,nick);
200 }
201 }
202 return nicks.get(user);
203 }
204
205 /**
206 * Retrieves the SHA-1 hash of a user's vCard PHOTO field.
207 * This information is cached.
208 *
209 * @param user the user whose information is fetched
210 * @param force do not use cached information
211 * @return the hash of the user's vCard PHOTO field
212 */
213 protected String getPhotoHash(String user, boolean force) {
214 if (!photoHashes.containsKey(user) || force) {
215 String photoHash = new String();
216 String photoBinVal = vcardManager.getVCardProperty(user,"PHOTO:BINVAL");
217 if (photoBinVal != null) {
218 photoHash = StringUtils.hash(StringUtils.decodeBase64(photoBinVal),"SHA-1");
219 }
220 photoHashes.put(user,photoHash);
221 }
222 return photoHashes.get(user);
223 }
224
225 /**
226 * Adds nickname information from a given user's vCard NICK field
227 * to a packet if the packet does not contain nickname information yet.
228 *
229 * @param packet the packet to modify
230 * @param user the user whose information is added to the packet
231 */
232 protected void addNick(Packet packet, String user) {
233 // Check if there already is a nickname
234 if (packet.getElement().element(QName.get("nick","http://jabber.org/protocol/nick")) != null)
235 return;
236
237 // Add the nickname
238 String nick = getNick(user,false);
239 if (nick.length() > 0) {
240 packet.getElement().addElement("nick","http://jabber.org/protocol/nick").setText(nick);
241 }
242 }
243
244 /**
245 * Adds the hash of a given user's vCard PHOTO field to a packet if the
246 * packet does not contain a photo hash yet.
247 *
248 * @param packet the packet to modify
249 * @param user the user whose information is added to the packet
250 */
251 protected void addPhotoHash(Packet packet, String user) {
252 // Check if there already is an <x> element and/or a photo hash
253 Element element = packet.getElement().element(QName.get("x","vcard-temp:x:update"));
254 if (element != null) {
255 if (element.element("photo") != null)
256 return;
257 }
258 else {
259 element = packet.getElement().addElement("x","vcard-temp:x:update");
260 }
261
262 // Add the photo hash
263 element.addElement("photo").addText(getPhotoHash(user,false));
264 }
265
266 public void vCardUpdated(String user) {
267 // Update hash tables
268 getNick(user,true);
269
270 boolean updatePresence = false;
271 String oldPhotoHash = (String) photoHashes.get(user);
272 if (!oldPhotoHash.equals(getPhotoHash(user,true))) {
273 updatePresence = true;
274 }
275
276 // Re-send all presences if necessary
277 if (updatePresence) {
278 for (Presence p : presenceManager.getPresences(user)) {
279 presenceRouter.route(p);
280 }
281 }
282 }
283
284 public void vCardCreated(String user) {
285 vCardUpdated(user);
286 }
287
288 public void vCardDeleted(String user) {
289 vCardUpdated(user);
290 }
291
292 public void propertySet(String property, Map params) {
293 if (property.equals("plugin.vcardextpres.photoHashEnabled")) {
294 photoHashEnabled = params.get("value").equals("true");
295 }
296 else if (property.equals("plugin.vcardextpres.nickEnabled")) {
297 nickEnabled = params.get("value").equals("true");
298 }
299 }
300
301 public void propertyDeleted(String property, Map params) {
302 if (property.equals("plugin.vcardextpres.photoHashEnabled")) {
303 photoHashEnabled = false;
304 }
305 else if (property.equals("plugin.vcardextpres.nickEnabled")) {
306 nickEnabled = false;
307 }
308 }
309
310 public void xmlPropertySet(String property, Map params) {
311 }
312
313 public void xmlPropertyDeleted(String property, Map params) {
314 }
315}
diff --git a/src/web/images/success-16x16.gif b/src/web/images/success-16x16.gif
new file mode 100644
index 0000000..93e8153
--- a/dev/null
+++ b/src/web/images/success-16x16.gif
Binary files differ
diff --git a/src/web/vcardextpres.jsp b/src/web/vcardextpres.jsp
new file mode 100644
index 0000000..f072520
--- a/dev/null
+++ b/src/web/vcardextpres.jsp
@@ -0,0 +1,130 @@
1<%@ page import="java.util.*,
2 org.jivesoftware.wildfire.XMPPServer,
3 org.jivesoftware.util.*,
4 org.jivesoftware.wildfire.plugin.VCardExtendedPresencePlugin"
5 errorPage="error.jsp"
6%>
7
8<%@ taglib uri="http://java.sun.com/jstl/core_rt" prefix="c" %>
9<%@ taglib uri="http://java.sun.com/jstl/fmt_rt" prefix="fmt" %>
10
11<% // Get parameters
12 boolean save = request.getParameter("save") != null;
13 boolean success = request.getParameter("success") != null;
14 boolean enableNick = ParamUtils.getBooleanParameter(request, "enableNick");
15 boolean enablePhotoHash = ParamUtils.getBooleanParameter(request, "enablePhotoHash");
16
17 VCardExtendedPresencePlugin plugin = (VCardExtendedPresencePlugin)XMPPServer.getInstance().getPluginManager().getPlugin("vcardextpres");
18
19 // Handle a save
20 if (save) {
21 plugin.setNickEnabled(enableNick);
22 plugin.setPhotoHashEnabled(enablePhotoHash);
23 response.sendRedirect("vcardextpres.jsp?success=true");
24 return;
25 }
26
27 enableNick = plugin.isNickEnabled();
28 enablePhotoHash = plugin.isPhotoHashEnabled();
29%>
30
31<html>
32 <head>
33 <title><fmt:message key="vcardextpres.config.title"/></title>
34 <meta name="pageID" content="vcardextpres"/>
35 </head>
36 <body>
37
38<p>
39<fmt:message key="vcardextpres.config.instructions"/>
40</p>
41
42<% if (success) { %>
43
44 <div class="jive-success">
45 <table cellpadding="0" cellspacing="0" border="0">
46 <tbody>
47 <tr><td class="jive-icon"><img src="images/success-16x16.gif" width="16" height="16" border="0"></td>
48 <td class="jive-icon-label">
49 <fmt:message key="vcardextpres.config.success"/>
50 </td></tr>
51 </tbody>
52 </table>
53 </div><br>
54<% } %>
55
56<form action="vcardextpres.jsp?save" method="post">
57
58<fieldset>
59 <legend><fmt:message key="vcardextpres.config.avatars.title"/></legend>
60 <div>
61 <p>
62 <fmt:message key="vcardextpres.config.avatars.description"/>
63 </p>
64 <table cellpadding="3" cellspacing="0" border="0" width="100%">
65 <tbody>
66 <tr>
67 <td width="1%">
68 <input type="radio" name="enablePhotoHash" value="true" id="rb01"
69 <%= ((enablePhotoHash) ? "checked" : "") %>>
70 </td>
71 <td width="99%">
72 <label for="rb01"><b><fmt:message key="vcardextpres.enabled"/></b> -
73 <fmt:message key="vcardextpres.config.avatars.enabled"/></label>
74 </td>
75 </tr>
76 <tr>
77 <td width="1%">
78 <input type="radio" name="enablePhotoHash" value="false" id="rb02"
79 <%= ((!enablePhotoHash) ? "checked" : "") %>>
80 </td>
81 <td width="99%">
82 <label for="rb02"><b><fmt:message key="vcardextpres.disabled"/></b> -
83 <fmt:message key="vcardextpres.config.avatars.disabled"/></label>
84 </td>
85 </tr>
86 </tbody>
87 </table>
88 </div>
89</fieldset>
90
91<br><br>
92
93<fieldset>
94 <legend><fmt:message key="vcardextpres.config.nick.title"/></legend>
95 <div>
96 <p>
97 <fmt:message key="vcardextpres.config.nick.description"/>
98 </p>
99 <table cellpadding="3" cellspacing="0" border="0" width="100%">
100 <tbody>
101 <tr>
102 <td width="1%">
103 <input type="radio" name="enableNick" value="true" id="rb01"
104 <%= ((enableNick) ? "checked" : "") %>>
105 </td>
106 <td width="99%">
107 <label for="rb01"><b><fmt:message key="vcardextpres.enabled"/></b> - <fmt:message key="vcardextpres.config.nick.enabled"/></label>
108 </td>
109 </tr>
110 <tr>
111 <td width="1%">
112 <input type="radio" name="enableNick" value="false" id="rb02"
113 <%= ((!enableNick) ? "checked" : "") %>>
114 </td>
115 <td width="99%">
116 <label for="rb02"><b><fmt:message key="vcardextpres.disabled"/></b> - <fmt:message key="vcardextpres.config.nick.disabled"/></label>
117 </td>
118 </tr>
119 </tbody>
120 </table>
121 </div>
122</fieldset>
123
124<br><br>
125
126<input type="submit" value="Save Properties">
127</form>
128
129</body>
130</html>