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