001    /**
002     *
003     *  Licensed to the Apache Software Foundation (ASF) under one or more
004     *  contributor license agreements.  See the NOTICE file distributed with
005     *  this work for additional information regarding copyright ownership.
006     *  The ASF licenses this file to You under the Apache License, Version 2.0
007     *  (the "License"); you may not use this file except in compliance with
008     *  the License.  You may obtain a copy of the License at
009     *
010     *     http://www.apache.org/licenses/LICENSE-2.0
011     *
012     *  Unless required by applicable law or agreed to in writing, software
013     *  distributed under the License is distributed on an "AS IS" BASIS,
014     *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
015     *  See the License for the specific language governing permissions and
016     *  limitations under the License.
017     */
018    package org.apache.geronimo.mail;
019    
020    import java.util.Properties;
021    
022    import org.apache.commons.logging.Log;
023    import org.apache.commons.logging.LogFactory;
024    
025    import org.apache.geronimo.gbean.GBeanInfo;
026    import org.apache.geronimo.gbean.GBeanInfoBuilder;
027    
028    
029    /**
030     * A GBean that provides for the configuration of a JavaMail POP3 message store
031     * protocol.
032     * <p/>
033     * POP3 store properties that are common to all POP3 stores are
034     * provided via member variables of this class.  Values that are set in the
035     * individual member variables will override any of the corresponding values
036     * that have been set in the properties set.
037     *
038     * @version $Rev: 470597 $ $Date: 2006-11-02 15:30:55 -0800 (Thu, 02 Nov 2006) $
039     * @see MailGBean
040     */
041    public class POP3StoreGBean extends ProtocolGBean {
042    
043        // the POP3 configuration property names
044        static public final String POP3_PORT = "mail.pop3.port";
045        static public final String POP3_CONNECTION_TIMEOUT = "mail.pop3.connectiontimeout";
046        static public final String POP3_TIMEOUT = "mail.pop3.timeout";
047        static public final String POP3_FACTORY_CLASS = "mail.pop3.socketFactory.class";
048        static public final String POP3_FACTORY_FALLBACK = "mail.pop3.socketFactory.fallback";
049        static public final String POP3_FACTORY_PORT = "mail.pop3.socketFactory.port";
050        static public final String POP3_LOCALHOST = "mail.pop3.localhost";
051        static public final String POP3_LOCALADDRESS = "mail.pop3.localaddress";
052        static public final String POP3_LOCALPORT = "mail.pop3.localport";
053        static public final String POP3_RESET = "mail.pop3.resetbeforequit";
054        static public final String POP3_MESSAGE_CLASS = "mail.pop3.message.class";
055        static public final String POP3_APOP = "mail.pop3.apop.enable";
056    
057        static public final String GBEAN_RESET = "rsetBeforeQuit";
058        static public final String GBEAN_APOP = "apopEnable";
059        static public final String GBEAN_MESSAGE_CLASS = "messageClass";
060    
061        private final Log log = LogFactory.getLog(POP3StoreGBean.class);
062    
063        private Integer port;
064        private Integer connectionTimeout;
065        private Integer timeout;
066        private Boolean rsetBeforeQuit;
067        private String messageClass;
068        private String localaddress;
069        private Integer localport;
070        private Boolean apopEnable;
071        private String socketFactoryClass;
072        private Boolean socketFactoryFallback;
073        private Integer socketFactoryPort;
074    
075    
076        /**
077         * Construct an instance of POP3StoreGBean
078         * <p/>
079         * Values that are set in the individual member variables will override any of
080         * the corresponding values that have been set in the properties set.
081         *
082         * @param objectName            the object name of the protocol
083         * @param properties            the set of default properties for the protocol
084         * @param host                  the host the protocol connects to
085         * @param user                  the default name for the protocol
086         * @param port                  the POP3 server port
087         * @param connectionTimeout     the socket connection timeout value in milliseconds
088         * @param timeout               the socket I/O timeout value in milliseconds
089         * @param rsetBeforeQuit        whether an attempt will be made send a POP3 RSET command when closing
090         *                              the folder, before sending the QUIT command
091         * @param messageClass          the class name of a subclass of com.sun.mail.pop3.POP3Message
092         * @param localaddress          the local address (host name) to bind to when creating the POP3 socket
093         * @param localport             the local port number to bind to when creating the POP3 socket
094         * @param apopEnable            whether to use APOP instead of USER/PASS to login to the POP3 server,
095         *                              if the POP3 server supports APOP
096         * @param socketFactoryClass    the class that will be used to create POP3 sockets
097         * @param socketFactoryFallback whether java.net.Socket class will be created if the specified
098         *                              socket factory class cannot be created
099         * @param socketFactoryPort     whether java.net.Socket class will be created if the specified
100         *                              socket factory class cannot be created
101         */
102        public POP3StoreGBean(String objectName, Properties properties, String host, String user,
103                              Integer port,
104                              Integer connectionTimeout,
105                              Integer timeout,
106                              Boolean rsetBeforeQuit,
107                              String messageClass,
108                              String localaddress,
109                              Integer localport,
110                              Boolean apopEnable,
111                              String socketFactoryClass,
112                              Boolean socketFactoryFallback,
113                              Integer socketFactoryPort) {
114            super(objectName, "pop3", properties, host, user);
115    
116            setPort(port);
117            setConnectionTimeout(connectionTimeout);
118            setTimeout(timeout);
119            setRsetBeforeQuit(rsetBeforeQuit);
120            setMessageClass(messageClass);
121            setLocaladdress(localaddress);
122            setLocalport(localport);
123            setApopEnable(apopEnable);
124            setSocketFactoryClass(socketFactoryClass);
125            setSocketFactoryFallback(socketFactoryFallback);
126            setSocketFactoryPort(socketFactoryPort);
127        }
128    
129        /**
130         * Returns the POP3 server port to connect to, if the connect() method
131         * doesn't explicitly specify one.
132         * <p/>
133         * Defaults to 110.
134         */
135        public Integer getPort() {
136            return port;
137        }
138    
139        /**
140         * Sets the POP3 server port to connect to, if the connect() method
141         * doesn't explicitly specify one.
142         * <p/>
143         * Defaults to 110.
144         * <p/>
145         * Values that are set here will override any of the corresponding value
146         * that has been set in the properties.
147         *
148         * @param port the POP3 server port to connect to, if the connect() method
149         *             doesn't explicitly specify one
150         */
151        public void setPort(Integer port) {
152            this.port = port;
153        }
154    
155        /**
156         * Returns the socket connection timeout value in milliseconds.
157         */
158        public Integer getConnectionTimeout() {
159            return connectionTimeout;
160        }
161    
162        /**
163         * Sets the socket connection timeout value in milliseconds.
164         * <p/>
165         * Default is infinite timeout.
166         * <p/>
167         * Values that are set here will override any of the corresponding value
168         * that has been set in the properties.
169         *
170         * @param connectionTimeout the socket connection timeout value in milliseconds.
171         */
172        public void setConnectionTimeout(Integer connectionTimeout) {
173            this.connectionTimeout = connectionTimeout;
174        }
175    
176        /**
177         * Returns the socket I/O timeout value in milliseconds.
178         */
179        public Integer getTimeout() {
180            return timeout;
181        }
182    
183        /**
184         * Sets the socket I/O timeout value in milliseconds.
185         * <p/>
186         * Default is infinite timeout.
187         * <p/>
188         * Values that are set here will override any of the corresponding value
189         * that has been set in the properties.
190         *
191         * @param timeout the socket I/O timeout value in milliseconds
192         */
193        public void setTimeout(Integer timeout) {
194            this.timeout = timeout;
195        }
196    
197        /**
198         * Returns whether an attempt will be made send a POP3 RSET command when
199         * closing the folder, before sending the QUIT command.
200         * <p/>
201         * Send a POP3 RSET command when closing the folder, before sending the
202         * QUIT command. Useful with POP3 servers that implicitly mark all
203         * messages that are read as "deleted"; this will prevent such messages
204         * from being deleted and expunged unless the client requests so. Default
205         * is false.
206         */
207        public Boolean getRsetBeforeQuit() {
208            return rsetBeforeQuit;
209        }
210    
211        /**
212         * Sets whether an attempt will be made send a POP3 RSET command when
213         * closing the folder, before sending the QUIT command.
214         * <p/>
215         * Send a POP3 RSET command when closing the folder, before sending the
216         * QUIT command. Useful with POP3 servers that implicitly mark all messages
217         * that are read as "deleted"; this will prevent such messages from being
218         * deleted and expunged unless the client requests so. Default is false.
219         * <p/>
220         * Values that are set here will override any of the corresponding value
221         * that has been set in the properties.
222         *
223         * @param rsetBeforeQuit whether an attempt will be made send a POP3 RSET command when
224         *                       closing the folder, before sending the QUIT command
225         */
226        public void setRsetBeforeQuit(Boolean rsetBeforeQuit) {
227            this.rsetBeforeQuit = rsetBeforeQuit;
228        }
229    
230        /**
231         * Returns the class name of a subclass of com.sun.mail.pop3.POP3Message.
232         * <p/>
233         * Class name of a subclass of com.sun.mail.pop3.POP3Message. The subclass
234         * can be used to handle (for example) non-standard Content-Type headers.
235         * The subclass must have a public constructor of the form
236         * MyPOP3Message(Folder f, int msgno) throws MessagingException.
237         */
238        public String getMessageClass() {
239            return messageClass;
240        }
241    
242        /**
243         * Sets the class name of a subclass of com.sun.mail.pop3.POP3Message.
244         * <p/>
245         * Class name of a subclass of com.sun.mail.pop3.POP3Message. The subclass
246         * can be used to handle (for example) non-standard Content-Type headers.
247         * The subclass must have a public constructor of the form
248         * MyPOP3Message(Folder f, int msgno) throws MessagingException.
249         * <p/>
250         * Values that are set here will override any of the corresponding value
251         * that has been set in the properties.
252         *
253         * @param messageClass the class name of a subclass of com.sun.mail.pop3.POP3Message.
254         */
255        public void setMessageClass(String messageClass) {
256            this.messageClass = messageClass;
257        }
258    
259        /**
260         * Returns the local address (host name) to bind to when creating the POP3 socket.
261         */
262        public String getLocaladdress() {
263            return localaddress;
264        }
265    
266        /**
267         * Sets the local address (host name) to bind to when creating the POP3 socket.
268         * <p/>
269         * Local address (host name) to bind to when creating the POP3 socket.
270         * Defaults to the address picked by the Socket class. Should not normally
271         * need to be set, but useful with multi-homed hosts where it's important
272         * to pick a particular local address to bind to.
273         * <p/>
274         * Values that are set here will override any of the corresponding value
275         * that has been set in the properties.
276         *
277         * @param localaddress the local address (host name) to bind to when creating the POP3 socket
278         */
279        public void setLocaladdress(String localaddress) {
280            this.localaddress = localaddress;
281        }
282    
283        /**
284         * Returns the local port number to bind to when creating the POP3 socket.
285         */
286        public Integer getLocalport() {
287            return localport;
288        }
289    
290        /**
291         * Sets the local port number to bind to when creating the POP3 socket.
292         * <p/>
293         * Local port number to bind to when creating the POP3 socket. Defaults to
294         * the port number picked by the Socket class.
295         * <p/>
296         * Values that are set here will override any of the corresponding value
297         * that has been set in the properties.
298         *
299         * @param localport the local port number to bind to when creating the POP3 socket
300         */
301        public void setLocalport(Integer localport) {
302            this.localport = localport;
303        }
304    
305        /**
306         * Returns whether to use APOP instead of USER/PASS to login to the POP3
307         * server, if the POP3 server supports APOP.
308         * <p/>
309         * If set to true, use APOP instead of USER/PASS to login to the POP3
310         * server, if the POP3 server supports APOP. APOP sends a digest of the
311         * password rather than the clear text password. Defaults to false.
312         */
313        public Boolean isApopEnable() {
314            return apopEnable;
315        }
316    
317        /**
318         * Sets whether to use APOP instead of USER/PASS to login to the POP3
319         * server, if the POP3 server supports APOP.
320         * <p/>
321         * If set to true, use APOP instead of USER/PASS to login to the POP3
322         * server, if the POP3 server supports APOP. APOP sends a digest of the
323         * password rather than the clear text password. Defaults to false.
324         *
325         * @param apopEnable whether to use APOP instead of USER/PASS to login to the POP3
326         *                   server, if the POP3 server supports APOP
327         */
328        public void setApopEnable(Boolean apopEnable) {
329            this.apopEnable = apopEnable;
330        }
331    
332        /**
333         * Returns the class that will be used to create POP3 sockets.
334         * <p/>
335         * If set, specifies the name of a class that implements the
336         * javax.net.SocketFactory interface. This class will be used to create POP3
337         * sockets.
338         */
339        public String getSocketFactoryClass() {
340            return socketFactoryClass;
341        }
342    
343        /**
344         * Sets the class that will be used to create POP3 sockets.
345         * <p/>
346         * If set, specifies the name of a class that implements the
347         * javax.net.SocketFactory interface. This class will be used to create POP3
348         * sockets.
349         * <p/>
350         * Values that are set here will override any of the corresponding value
351         * that has been set in the properties.
352         *
353         * @param socketFactoryClass the class that will be used to create POP3 sockets
354         */
355        public void setSocketFactoryClass(String socketFactoryClass) {
356            this.socketFactoryClass = socketFactoryClass;
357        }
358    
359        /**
360         * Returns whether java.net.Socket class will be created if the specified
361         * socket factory class cannot be created.
362         * <p/>
363         * If set to true, failure to create a socket using the specified socket
364         * factory class will cause the socket to be created using the
365         * java.net.Socket class. Defaults to true.
366         */
367        public Boolean isSocketFactoryFallback() {
368            return socketFactoryFallback;
369        }
370    
371        /**
372         * Sets whether java.net.Socket class will be created if the specified
373         * socket factory class cannot be created.
374         * <p/>
375         * If set to true, failure to create a socket using the specified socket
376         * factory class will cause the socket to be created using the
377         * java.net.Socket class. Defaults to true.
378         * <p/>
379         * Values that are set here will override any of the corresponding value
380         * that has been set in the properties.
381         *
382         * @param socketFactoryFallback whether java.net.Socket class will be created if the specified
383         *                              socket factory class cannot be created
384         */
385        public void setSocketFactoryFallback(Boolean socketFactoryFallback) {
386            this.socketFactoryFallback = socketFactoryFallback;
387        }
388    
389        /**
390         * Returns the port to connect to when using the specified socket factory.
391         * <p/>
392         * Specifies the port to connect to when using the specified socket
393         * factory. If not set, the default port will be used.
394         */
395        public Integer getSocketFactoryPort() {
396            return socketFactoryPort;
397        }
398    
399        /**
400         * Sets the port to connect to when using the specified socket factory.
401         * <p/>
402         * Specifies the port to connect to when using the specified socket
403         * factory. If not set, the default port will be used.
404         * <p/>
405         * Values that are set here will override any of the corresponding value
406         * that has been set in the properties.
407         *
408         * @param socketFactoryPort the port to connect to when using the specified socket factory
409         */
410        public void setSocketFactoryPort(Integer socketFactoryPort) {
411            this.socketFactoryPort = socketFactoryPort;
412        }
413    
414        /**
415         * Add the overrides from the member variables to the properties file.
416         */
417        public void addOverrides(Properties props) {
418            super.addOverrides(props);
419    
420            if (port != null) props.setProperty(POP3_PORT, port.toString());
421            if (connectionTimeout != null) props.setProperty(POP3_CONNECTION_TIMEOUT, connectionTimeout.toString());
422            if (timeout != null) props.setProperty(POP3_TIMEOUT, timeout.toString());
423            if (rsetBeforeQuit != null) props.setProperty(POP3_RESET, rsetBeforeQuit.toString());
424            if (messageClass != null) props.setProperty(POP3_MESSAGE_CLASS, messageClass);
425            if (localaddress != null) props.setProperty(POP3_LOCALADDRESS, localaddress);
426            if (localport != null) props.setProperty(POP3_LOCALPORT, localport.toString());
427            if (apopEnable != null) props.setProperty(POP3_APOP, apopEnable.toString());
428            if (socketFactoryClass != null) props.setProperty(POP3_FACTORY_CLASS, socketFactoryClass);
429            if (socketFactoryFallback != null) props.setProperty(POP3_FACTORY_FALLBACK, socketFactoryFallback.toString());
430            if (socketFactoryPort != null) props.setProperty(POP3_FACTORY_PORT, socketFactoryPort.toString());
431        }
432    
433        public void doStart() throws Exception {
434            log.debug("Started " + getObjectName());
435        }
436    
437        public void doStop() throws Exception {
438            log.debug("Stopped " + getObjectName());
439        }
440    
441        public void doFail() {
442            log.warn("Failed " + getObjectName());
443        }
444    
445        public static final GBeanInfo GBEAN_INFO;
446    
447        static {
448            GBeanInfoBuilder infoFactory = GBeanInfoBuilder.createStatic(POP3StoreGBean.class, ProtocolGBean.GBEAN_INFO);
449    
450            infoFactory.addAttribute(GBEAN_PORT, Integer.class, true);
451            infoFactory.addAttribute(GBEAN_CONNECTION_TIMEOUT, Integer.class, true);
452            infoFactory.addAttribute(GBEAN_TIMEOUT, Integer.class, true);
453            infoFactory.addAttribute(GBEAN_RESET, Boolean.class, true);
454            infoFactory.addAttribute(GBEAN_MESSAGE_CLASS, String.class, true);
455            infoFactory.addAttribute(GBEAN_LOCALADDRESS, String.class, true);
456            infoFactory.addAttribute(GBEAN_LOCALPORT, Integer.class, true);
457            infoFactory.addAttribute(GBEAN_APOP, Boolean.class, true);
458            infoFactory.addAttribute(GBEAN_FACTORY_CLASS, String.class, true);
459            infoFactory.addAttribute(GBEAN_FACTORY_FALLBACK, Boolean.class, true);
460            infoFactory.addAttribute(GBEAN_FACTORY_PORT, Integer.class, true);
461    
462            infoFactory.addAttribute(GBEAN_OBJECTNAME, String.class, false);
463            infoFactory.addAttribute(GBEAN_PROTOCOL, String.class, true);
464            infoFactory.addAttribute(GBEAN_PROPERTIES, Properties.class, true);
465            infoFactory.addAttribute(GBEAN_HOST, String.class, true);
466            infoFactory.addAttribute(GBEAN_USER, String.class, true);
467            infoFactory.addOperation(GBEAN_ADD_OVERRIDES, new Class[]{Properties.class});
468    
469            infoFactory.setConstructor(new String[]{GBEAN_OBJECTNAME, GBEAN_PROPERTIES, GBEAN_HOST, GBEAN_USER,
470                                                    GBEAN_PORT,
471                                                    GBEAN_CONNECTION_TIMEOUT,
472                                                    GBEAN_TIMEOUT,
473                                                    GBEAN_RESET,
474                                                    GBEAN_MESSAGE_CLASS,
475                                                    GBEAN_LOCALADDRESS,
476                                                    GBEAN_LOCALPORT,
477                                                    GBEAN_APOP,
478                                                    GBEAN_FACTORY_CLASS,
479                                                    GBEAN_FACTORY_FALLBACK,
480                                                    GBEAN_FACTORY_PORT});
481    
482            GBEAN_INFO = infoFactory.getBeanInfo();
483        }
484    
485        public static GBeanInfo getGBeanInfo() {
486            return GBEAN_INFO;
487        }
488    }