001/*
002 * CDDL HEADER START
003 *
004 * The contents of this file are subject to the terms of the
005 * Common Development and Distribution License, Version 1.0 only
006 * (the "License").  You may not use this file except in compliance
007 * with the License.
008 *
009 * You can obtain a copy of the license at legal-notices/CDDLv1_0.txt
010 * or http://forgerock.org/license/CDDLv1.0.html.
011 * See the License for the specific language governing permissions
012 * and limitations under the License.
013 *
014 * When distributing Covered Code, include this CDDL HEADER in each
015 * file and include the License file at legal-notices/CDDLv1_0.txt.
016 * If applicable, add the following below this CDDL HEADER, with the
017 * fields enclosed by brackets "[]" replaced with your own identifying
018 * information:
019 *      Portions Copyright [yyyy] [name of copyright owner]
020 *
021 * CDDL HEADER END
022 *
023 *
024 *      Copyright 2008 Sun Microsystems, Inc.
025 */
026
027package org.forgerock.opendj.config;
028
029import org.forgerock.util.Reject;
030
031import java.net.InetAddress;
032import java.net.UnknownHostException;
033import java.util.EnumSet;
034
035/**
036 * IP address property definition.
037 */
038public final class IPAddressPropertyDefinition extends PropertyDefinition<InetAddress> {
039
040    /**
041     * An interface for incrementally constructing IP address property
042     * definitions.
043     */
044    public static final class Builder extends AbstractBuilder<InetAddress, IPAddressPropertyDefinition> {
045
046        /** Private constructor. */
047        private Builder(AbstractManagedObjectDefinition<?, ?> d, String propertyName) {
048            super(d, propertyName);
049        }
050
051        /** {@inheritDoc} */
052        @Override
053        protected IPAddressPropertyDefinition buildInstance(AbstractManagedObjectDefinition<?, ?> d,
054            String propertyName, EnumSet<PropertyOption> options, AdministratorAction adminAction,
055            DefaultBehaviorProvider<InetAddress> defaultBehavior) {
056            return new IPAddressPropertyDefinition(d, propertyName, options, adminAction, defaultBehavior);
057        }
058
059    }
060
061    /**
062     * Create a IP address property definition builder.
063     *
064     * @param d
065     *            The managed object definition associated with this property
066     *            definition.
067     * @param propertyName
068     *            The property name.
069     * @return Returns the new IP address property definition builder.
070     */
071    public static Builder createBuilder(AbstractManagedObjectDefinition<?, ?> d, String propertyName) {
072        return new Builder(d, propertyName);
073    }
074
075    /** Private constructor. */
076    private IPAddressPropertyDefinition(AbstractManagedObjectDefinition<?, ?> d, String propertyName,
077        EnumSet<PropertyOption> options, AdministratorAction adminAction,
078        DefaultBehaviorProvider<InetAddress> defaultBehavior) {
079        super(d, InetAddress.class, propertyName, options, adminAction, defaultBehavior);
080    }
081
082    /** {@inheritDoc} */
083    @Override
084    public void validateValue(InetAddress value) {
085        Reject.ifNull(value);
086
087        // No additional validation required.
088    }
089
090    /** {@inheritDoc} */
091    @Override
092    public InetAddress decodeValue(String value) {
093        Reject.ifNull(value);
094
095        try {
096            return InetAddress.getByName(value);
097        } catch (UnknownHostException e) {
098            // TODO: it would be nice to throw the cause.
099            throw PropertyException.illegalPropertyValueException(this, value);
100        }
101    }
102
103    /** {@inheritDoc} */
104    @Override
105    public String encodeValue(InetAddress value) {
106        // We should return the host name if it is available, or the IP
107        // address if not.
108
109        // Unforunately, there is no InetAddress method for doing this, so
110        // we have to resort to hacking at the toString() encoding.
111        String s = value.toString();
112        int i = s.indexOf('/');
113        if (i > 0) {
114            // Host address is before the forward slash.
115            return s.substring(0, i);
116        } else {
117            return value.getHostAddress();
118        }
119    }
120
121    /** {@inheritDoc} */
122    @Override
123    public <R, P> R accept(PropertyDefinitionVisitor<R, P> v, P p) {
124        return v.visitIPAddress(this, p);
125    }
126
127    /** {@inheritDoc} */
128    @Override
129    public <R, P> R accept(PropertyValueVisitor<R, P> v, InetAddress value, P p) {
130        return v.visitIPAddress(this, value, p);
131    }
132
133    /** {@inheritDoc} */
134    @Override
135    public int compare(InetAddress o1, InetAddress o2) {
136        return o1.getHostAddress().compareTo(o2.getHostAddress());
137    }
138}