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( final 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( final 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       // Comparable
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         * <del>HybsEntryは、key が等しく、かつ valueが同一の場合に、等しいと判断されます。</del>
153         * HybsEntryは、key,value,comment が同一の場合に、等しいと判断されます。( 8.4.2.2 (2023/03/17) )
154         *
155         * @og.rev 8.4.2.2 (2023/03/17) ハッシュコード求めに対応した、equals に変更します。
156         *
157         * @param   object 比較対象の参照オブジェクト
158         *
159         * @return      引数に指定されたオブジェクトとこのオブジェクトが等しい場合は true、そうでない場合は false
160         */
161        @Override
162        public boolean equals( final Object object ) {
163                if( object instanceof HybsEntry ) {
164                        final HybsEntry other = (HybsEntry)object;
165                        return  key.equals( other.key )
166                                        && value   != null && value.equals( other.value )
167                                        && comment != null && value.equals( other.comment ) ;
168                }
169                return false ;
170        }
171
172        /**
173         * オブジェクトのハッシュコード値を返します。
174         * このメソッドは、java.util.Hashtable によって提供されるような
175         * ハッシュテーブルで使用するために用意されています。
176         * equals( Object ) メソッドをオーバーライトした場合は、hashCode() メソッドも
177         * 必ず 記述する必要があります。
178         * ここでは、key と value の合成した文字列のハッシュコード値を返します。
179         *
180         * @return  このオブジェクトのハッシュコード値
181         *
182         */
183        @Override
184        public int hashCode() { return hCode ; }
185
186        /**
187         * オブジェクトの識別子として、詳細なユーザー情報を返します。
188         *
189         * @return  詳細なユーザー情報
190         * @og.rtnNotNull
191         */
192        @Override
193        public String toString() {
194                return "key=[" + key + "],value=[" + value + "],comment=[" + comment + "]" ;
195        }
196
197        /**
198         * 設定値の順序を表す Comparator を返します。
199         * HybsEntryクラス自身は、key の順番で自然順序付けを行う、Comparable インターフェースを
200         * 実装しています。しかし、設定値でソートする場合は、この
201         * Comparator インターフェースを実装した内部クラスを使用することで、
202         * 対応出来ます。
203         *
204         * @return  設定値の順序を表す Comparator
205         */
206        //      public Comparator getValueComparator() {
207        //              return valueComp ;
208        //      }
209
210        /**
211         * オブジェクトの識別子として、詳細なユーザー情報を返します。
212         *
213         * @return  詳細なユーザー情報
214         */
215        //      private static class ValueComparator implements Comparator {
216        //              /**
217        //               * value の順序付けのために 2 つの引数を比較します。
218        //               * 最初の引数が 2 番目の引数より小さい場合は負の整数、両方が等しい場合は 0、
219        //               * 最初の引数が 2 番目の引数より大きい場合は正の整数を返します。
220        //               *
221        //               * @param   o1 Object 比較対象の最初のオブジェクト
222        //               * @param   o2 Objectb比較対象の 2 番目のオブジェクト
223        //               * @return  最初の引数が 2 番目の引数より小さい場合は負の整数、両方が等しい場合は 0、最初の引数が 2 番目の引数より大きい場合は正の整数
224        //               * @throws  ClassCastException - 引数の型がこのコンパレータによる比較を妨げる場合
225        //               */
226        //              public int compare(Object o1, Object o2) {
227        //                      HybsEntry e1 = (HybsEntry)o1 ;          // キャスト失敗で、ClassCastException
228        //                      HybsEntry e2 = (HybsEntry)o2 ;          // キャスト失敗で、ClassCastException
229        //
230        //                      int comp = 0;
231        //                      if( e1 == null && e2 == null ) { comp = 0; }
232        //                      else if( e1 == null && e2 != null ) { comp = -1; }
233        //                      else if( e1 != null && e2 == null ) { comp = 1;  }
234        //                      else if( e1 != null && e2 != null ) {
235        //                              if( e1.value == null && e2.value == null ) { comp = 0; }
236        //                              else if( e1.value == null && e2.value != null ) { comp = -1; }
237        //                              else if( e1.value != null && e2.value == null ) { comp = 1; }
238        //                              else {
239        //                                      comp = e1.value.compareTo( e2.value );
240        //                              }
241        //                      }
242        //                      return comp ;
243        //              }
244        //      }
245}