    001/*
    002 * Copyright (c) 2009 The openGion Project.
    003 *
    004 * Licensed under the Apache License, Version 2.0 (the "License");
    005 * you may not use this file except in compliance with the License.
    006 * You may obtain a copy of the License at
    007 *
    008 *     http://www.apache.org/licenses/LICENSE-2.0
    009 *
    010 * Unless required by applicable law or agreed to in writing, software
    011 * distributed under the License is distributed on an "AS IS" BASIS,
    012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
    013 * either express or implied. See the License for the specific language
    014 * governing permissions and limitations under the License.
    015 */
    016package org.opengion.fukurou.util;
    017
    018/**
    019 * HybsEntry.java は、内部に final 定義された文字列の、key と value を持つ、値クラスです。
    020 *
    021 * 全変数は、public final 宣言されており、外部より取得できますが、設定できません。
    022 * このクラスは、コンストラクタで設定されたキーと設定値を変える事が出来ません。
    023 * よって、デフォルトコンストラクタを持たないため、java.io.Serializable インターフェースは
    024 * 持ちません。また、内部の値を変更できない為、clone() をする必要がないため、
    025 * java.lang.Cloneable インターフェースも実装していません。
    026 * HybsEntry オブジェクトの同一性を確保するには、equals( Object ) と、hashCode() メソッドを
    027 * オーバーライドしておく必要があります。同一性の条件は、key と value が、ともに
    028 * String.equals の関係を持てば、成立することとします。
    029 *
    030 * @version  4.0
    031 * @author       Kazuhiko Hasegawa
    032 * @since    JDK5.0,
    033 */
    034public final class HybsEntry implements Comparable<HybsEntry> { // 4.3.3.6 (2008/11/15) Generics警告対応
    035        /** 内部のキー情報     */
    036        private final String key ;
    037        /** 内部のバリュー情報   */
    038        private final String value ;
    039        /** 内部のコメント情報   */
    040        private final String comment ;  // 4.0.0 (2005/01/31) 追加
    041
    042        // 4.0.0 (2005/01/31) private 化
    043        private final int hCode ;
    044        //      private static final ValueComparator valueComp = new ValueComparator();
    045
    046        /**
    047         * コンストラクタ
    048         * 内部変数への値の設定は、このコンストラクターで行われます。
    049         * key への null セットは認められません。value へは、セットできます。
    050         * コメントは、ゼロ文字列("") で、初期化されます。
    051         *
    052         * @param key   キー
    053         * @param value 値
    054         * @throws IllegalArgumentException key に null がセットされた場合
    055         */
    056        public HybsEntry( String key,final String value ) {
    057                this( key,value,"" );
    058        }
    059
    060        /**
    061         * コンストラクタ
    062         * 内部変数への値の設定は、このコンストラクターで行われます。
    063         * key への null セットは認められません。value へは、セットできます。
    064         *
    065         * @param key   キー
    066         * @param value 値
    067         * @param comment コメント
    068         * @throws IllegalArgumentException key に null がセットされた場合
    069         */
    070        public HybsEntry( String key,final String value,final String comment ) {
    071                if( key == null ) {
    072                        final String errMsg = "key への null セットは認められません。" ;
    073                        throw new IllegalArgumentException( errMsg );
    074                }
    075
    076                this.key        = key;
    077                this.value      = value;
    078                this.comment = comment;
    079                hCode           = ( key + ',' + value + '.' + comment ).hashCode();
    080        }
    081
    082        /**
    083         * エントリに対応するキーを返します。
    084         *
    085         * @return      エントリに対応するキー
    086         */
    087        public String getKey() { return key; }
    088
    089        /**
    090         * エントリに対応する値を返します。
    091         *
    092         * @return      エントリに対応する値
    093         */
    094        public String getValue() { return value; }
    095
    096        /**
    097         * エントリに対応するコメントを返します。
    098         *
    099         * @return エントリに対応するコメント
    100         */
    101        public String getComment() { return comment; }
    102
    103        /**
    104         * HybsEntry の設定されている値を変更します。
    105         * これは、設定値を変更した新しい HybsEntry を作成して返します。
    106         * なお、value が、内部の値と等しい時(equals が成立する時)自分自身を返します。
    107         *
    108         * @param newValue 新しい値
    109         *
    110         * @return エントリー HybsEntry
    111         * @og.rtnNotNull
    112         */
    113        public HybsEntry getValue( final String newValue ) {
    114                // 6.4.1.1 (2016/01/16) PMD refactoring. A method should have only one exit point, and that should be the last statement in the method
    115                return  ( newValue == null && value == null ) ||
    116                                ( newValue != null && newValue.equals( value ) )
    117                                        ? this
    118                                        : new HybsEntry( key,newValue,comment );
    119        }
    120
    121        /**
    122         * 自然比較メソッド
    123         * インタフェース Comparable の 実装です。
    124         * HybsEntryの順序は、key の順序であらわされます。
    125         * 同一keyの場合は，value の順番になります。
    126         *
    127         * @param   other 比較対象のObject
    128         *
    129         * @return  このオブジェクトが指定されたオブジェクトより小さい場合は負の整数、等しい場合はゼロ、大きい場合は正の整数
    130         * @throws ClassCastException 指定されたオブジェクトがキャストできない場合。
    131         */
    132        @Override
    133        public int compareTo( final HybsEntry other ) {         // 4.3.3.6 (2008/11/15) Generics警告対応
    134                int comp = key.compareTo( other.key );
    135
    136                if( comp == 0 ) {
    137                        // 6.4.1.1 (2016/01/16) PMD refactoring. Avoid if (x != y) ..; else ..;
    138                        comp = value == null
    139                                        ? other.value == null ? 0 : -1                                  // value が null 同士で、一致って ???
    140                                        : value.compareTo( other.value );
    141
    142                        if( comp == 0 ) {
    143                                comp = comment.compareTo( other.comment );
    144                        }
    145                }
    146                return comp ;
    147        }
    148
    149        /**
    150         * このオブジェクトと他のオブジェクトが等しいかどうかを示します。
    151         * インタフェース Comparable の 実装に関連して、再定義しています。
    152         * HybsEntryは、key が等しく、かつ valueが同一の場合に、
    153         * 等しいと判断されます。
    154         *
    155         * @param   object 比較対象の参照オブジェクト
    156         *
    157         * @return      引数に指定されたオブジェクトとこのオブジェクトが等しい場合は true、そうでない場合は false
    158         */
    159        @Override
    160        public boolean equals( final Object object ) {
    161                if( object instanceof HybsEntry ) {
    162                        final HybsEntry other = (HybsEntry)object;
    163                        return  key.equals( other.key )
    164                                        && value != null && value.equals( other.value ) ;
    165                }
    166                return false ;
    167        }
    168
    169        /**
    170         * オブジェクトのハッシュコード値を返します。
    171         * このメソッドは、java.util.Hashtable によって提供されるような
    172         * ハッシュテーブルで使用するために用意されています。
    173         * equals( Object ) メソッドをオーバーライトした場合は、hashCode() メソッドも
    174         * 必ず 記述する必要があります。
    175         * ここでは、key と value の合成した文字列のハッシュコード値を返します。
    176         *
    177         * @return  このオブジェクトのハッシュコード値
    178         *
    179         */
    180        @Override
    181        public int hashCode() {
    182                return hCode ;
    183        }
    184
    185        /**
    186         * オブジェクトの識別子として，詳細なユーザー情報を返します。
    187         *
    188         * @return  詳細なユーザー情報
    189         * @og.rtnNotNull
    190         */
    191        @Override
    192        public String toString() {
    193                return "key=[" + key + "],value=[" + value + "],comment=[" + comment + "]" ;
    194        }
    195
    196        /**
    197         * 設定値の順序を表す Comparator を返します。
    198         * HybsEntryクラス自身は、key の順番で自然順序付けを行う、Comparable インターフェースを
    199         * 実装しています。しかし、設定値でソートする場合は、この
    200         * Comparator インターフェースを実装した内部クラスを使用することで、
    201         * 対応出来ます。
    202         *
    203         * @return  設定値の順序を表す Comparator
    204         */
    205        //      public Comparator getValueComparator() {
    206        //              return valueComp ;
    207        //      }
    208
    209        /**
    210         * オブジェクトの識別子として，詳細なユーザー情報を返します。
    211         *
    212         * @return  詳細なユーザー情報
    213         */
    214        //      private static class ValueComparator implements Comparator {
    215        //              /**
    216        //               * value の順序付けのために 2 つの引数を比較します。
    217        //               * 最初の引数が 2 番目の引数より小さい場合は負の整数、両方が等しい場合は 0、
    218        //               * 最初の引数が 2 番目の引数より大きい場合は正の整数を返します。
    219        //               *
    220        //               * @param   o1 Object 比較対象の最初のオブジェクト
    221        //               * @param   o2 Objectb比較対象の 2 番目のオブジェクト
    222        //               * @return  最初の引数が 2 番目の引数より小さい場合は負の整数、両方が等しい場合は 0、最初の引数が 2 番目の引数より大きい場合は正の整数
    223        //               * @throws  ClassCastException - 引数の型がこのコンパレータによる比較を妨げる場合
    224        //               */
    225        //              public int compare(Object o1, Object o2) {
    226        //                      HybsEntry e1 = (HybsEntry)o1 ;          // キャスト失敗で、ClassCastException
    227        //                      HybsEntry e2 = (HybsEntry)o2 ;          // キャスト失敗で、ClassCastException
    228        //
    229        //                      int comp = 0;
    230        //                      if( e1 == null && e2 == null ) { comp = 0; }
    231        //                      else if( e1 == null && e2 != null ) { comp = -1; }
    232        //                      else if( e1 != null && e2 == null ) { comp = 1;  }
    233        //                      else if( e1 != null && e2 != null ) {
    234        //                              if( e1.value == null && e2.value == null ) { comp = 0; }
    235        //                              else if( e1.value == null && e2.value != null ) { comp = -1; }
    236        //                              else if( e1.value != null && e2.value == null ) { comp = 1; }
    237        //                              else {
    238        //                                      comp = e1.value.compareTo( e2.value );
    239        //                              }
    240        //                      }
    241        //                      return comp ;
    242        //              }
    243        //      }
    244}