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 */
016 package org.opengion.fukurou.process;
017
018 import org.opengion.fukurou.util.Argument;
019
020 import org.opengion.fukurou.util.StringUtil;
021 import org.opengion.fukurou.util.HybsEntry ;
022 import org.opengion.fukurou.util.LogWriter;
023
024 import java.util.Hashtable;
025 import java.util.List;
026 import java.util.ArrayList;
027 import java.util.Map ;
028 import java.util.LinkedHashMap ;
029
030 import javax.naming.Context;
031 import javax.naming.NamingEnumeration;
032 import javax.naming.NamingException;
033 import javax.naming.directory.DirContext;
034 import javax.naming.directory.InitialDirContext;
035 import javax.naming.directory.SearchControls;
036 import javax.naming.directory.SearchResult;
037 import javax.naming.directory.Attribute;
038 import javax.naming.directory.Attributes;
039
040 /**
041 * Process_LDAPReaderは、LDAPから読み取ったå?容をã?LineModel に設定後ã?
042 * 下流に渡すã?FirstProcess インターフェースの実è£?‚¯ラスですã?
043 *
044 * LDAPから読み取ったå?容より、LineModelを作æ?しã?下æµ?プロセスチェインはã€?
045 * チェインしてã�?‚‹ため、データは上流から下流へと渡されますã?)に渡しますã?
046 *
047 * 引数æ–?—å?中にスペã?スを含ã‚??合ã?、ダブルコーãƒ??ション("") で括って下さã�??
048 * 引数æ–?—å?の ã€?』ã?前後には、スペã?スは挟めません。å¿?�šã€?key=value の様に
049 * 繋げてくださいã€?
050 *
051 * @og.formSample
052 * Process_LDAPReader -attrs=uid,cn,officeName,ou,mail,belongOUID -orderBy=uid -filter=(&(objectClass=person)(|(belongOUID=61200)(belongOUID=61100)))
053 *
054 * [ -initctx=コンãƒ?‚ストファクトリ ] ?šå?期コンãƒ?‚ストファクトリ (初期値:com.sun.jndi.ldap.LdapCtxFactory)
055 * [ -providerURL=サービスプロバイãƒ?ƒª ] ?šサービスプロバイãƒ?ƒª (初期値:ldap://ldap.opengion.org:389)
056 * [ -entrydn=取得å?の名前 ] ?š属æ?の取得å?のオブジェクトã?名前 (初期値:cn=inquiry-sys,o=opengion,c=JP)
057 * [ -password=取得å?のパスワーãƒ? ] ?š属æ?の取得å?のパスワーãƒ? (初期値:******)
058 * [ -searchbase=コンãƒ?‚ストã?ースå�? ] ?š検索するコンãƒ?‚ストã?ベã?スå�?(初期値:soouid=employeeuser,o=opengion,c=JP)
059 * [ -searchScope=検索ç¯?›² ] ?š検索ç¯?›²。ã?OBJECT』ã?ONELEVEL』ã?SUBTREE』ã?どれか(初期値:SUBTREE)
060 * [ -timeLimit=検索制限時é–? ] ?š結果が返されるまでのミリ秒数ã€? の場合無制é™?初期値:0)
061 * [ -attrs=属æ?の識別å? ] ?šエントリとä¸?·’に返される属æ?の識別子ã?null の場合すべての属æ?
062 * [ -columns=属æ?のカラãƒ?�� ] ?š属æ?の識別子に対する別名ã?識別子と同じ場合ã?ã€?』ã?みで区åˆ?‚‹ã€?
063 * [ -maxRowCount=æœ?¤§検索数 ] ?š最大検索数(初期値:0[無制限])
064 * [ -match_XXXX=正規表現 ] ?š指定ã?カラãƒ?�¨正規表現でä¸??時ã?み処ç�? -match_LANG=ABC=[a-zA-Z]* などã€?
065 * [ -filter=検索条件 ] ?š検索する LDAP にæŒ?®šする条件
066 * [ -referral=REFERAL ] ?šignore/follow/throw
067 * [ -display=[false/true] ] ?š結果を標準å?力に表示する(true)かしなã�?false)ã�?初期値:false[表示しない])
068 * [ -debug=[false/true] ] ?šデバッグæƒ??を標準å?力に表示する(true)かしなã�?false)ã�?初期値:false[表示しない])
069 *
070 * @version 4.0
071 * @author Kazuhiko Hasegawa
072 * @since JDK5.0,
073 */
074 public class Process_LDAPReader extends AbstractProcess implements FirstProcess {
075 private static final String INITCTX = "com.sun.jndi.ldap.LdapCtxFactory";
076 private static final String PROVIDER = "ldap://ldap.opengion.org:389";
077 private static final String PASSWORD = "password";
078 private static final String SEARCH_BASE = "soouid=employeeuser,o=opengion,c=JP";
079 private static final String ENTRYDN = "cn=inquiry-sys,o=opengion,c=JP"; // 4.2.2.0 (2008/05/10)
080 private static final String REFERRAL = ""; // 5.6.7.0 (2013/07/27)
081
082 // 検索ç¯?›²。OBJECT_SCOPE、ONELEVEL_SCOPE、SUBTREE_SCOPE のどれか 1 つ
083 private static final String[] SCOPE_LIST = new String[] { "OBJECT","ONELEVEL","SUBTREE" };
084 private static final String SEARCH_SCOPE = "SUBTREE";
085
086 private static final long COUNT_LIMIT = 0; // 返すエントリのæœ?¤§数ã€? の場合ã?フィルタをæº?�Ÿすエントリをすべて返す
087
088 private String filter = null; // "employeeNumber=87019";
089 private int timeLimit = 0; // 結果が返されるまでのミリ秒数ã€? の場合ã?無制é™?
090 private String[] attrs = null; // エントリとä¸?·’に返される属æ?の識別子ã?null の場合ã?すべての属æ?を返す。空の場合ã?属æ?を返さなã�?
091 private String[] columns = null; // 属æ?の識別子に対する、別名ã?識別子と同じ場合ã?、ã?,』ã?みで区åˆ?‚‹ã€?
092 private static final boolean RETURN_OBJ_FLAG = false; // true の場合ã?エントリの名前にバインドされたオブジェクトを返す。false 場合ã?オブジェクトを返さなã�?
093 private static final boolean DEREF_LINK_FLAG = false; // true の場合ã?検索中にリンクを間接参ç?する
094
095 private int executeCount = 0; // 検索/実行件数
096 private int maxRowCount = 0; // æœ?¤§検索数(0は無制é™?
097
098 // 3.8.0.9 (2005/10/17) 正規表現マッãƒ?
099 private String[] matchKey = null; // 正規表現
100 private boolean display = false; // 表示しなã�?
101 private boolean debug = false; // 5.7.3.0 (2014/02/07) ãƒ?ƒ�ãƒ?‚°æƒ??
102
103 private static final Map<String,String> mustProparty ; // ?»プロパティ?½å¿??チェãƒ?‚¯用 Map
104 private static final Map<String,String> usableProparty ; // ?»プロパティ?½整合æ?チェãƒ?‚¯ Map
105
106 private NamingEnumeration<SearchResult> nameEnum = null; // 4.3.3.6 (2008/11/15) Generics警告対å¿?
107 private LineModel newData = null;
108 private int count = 0;
109
110 static {
111 mustProparty = new LinkedHashMap<String,String>();
112 mustProparty.put( "filter", "検索条件(å¿??) ä¾? (&(objectClass=person)(|(belongOUID=61200)(belongOUID=61100)))" );
113
114 usableProparty = new LinkedHashMap<String,String>();
115 usableProparty.put( "initctx", "初期コンãƒ?‚ストファクトリã€? +
116 CR + " (初期値:com.sun.jndi.ldap.LdapCtxFactory)" );
117 usableProparty.put( "providerURL", "サービスプロバイãƒ?ƒª (初期値:ldap://ldap.opengion.org:389)" );
118 usableProparty.put( "entrydn", "属æ?の取得å?のオブジェクトã?名前ã€? +
119 CR + " (初期値:cn=inquiry-sys,o=opengion,c=JP)" );
120 usableProparty.put( "password", "属æ?の取得å?のパスワーãƒ?初期値:******)" );
121 usableProparty.put( "searchbase", "検索するコンãƒ?‚ストã?ベã?ス名ã?" +
122 CR + " (初期値:soouid=employeeuser,o=opengion,c=JP)" );
123 usableProparty.put( "searchScope", "検索ç¯?›²。ã?OBJECT』ã?ONELEVEL』ã?SUBTREE』ã?どれかã€? +
124 CR + " (初期値:SUBTREE)" );
125 usableProparty.put( "timeLimit", "結果が返されるまでのミリ秒数ã€? の場合無制é™?初期値:0)" );
126 usableProparty.put( "attrs", "エントリとä¸?·’に返される属æ?の識別子ã?null の場合すべての属æ?" );
127 usableProparty.put( "columns", "属æ?の識別子に対する別名ã?識別子と同じ場合ã?ã€?』ã?みで区åˆ?‚‹ã€? );
128 usableProparty.put( "maxRowCount", "æœ?¤§検索数(0は無制é™? (初期値:0)" );
129 usableProparty.put( "match_", "æŒ?®šã?カラãƒ?�¨正規表現でä¸??時ã?み処ç�? +
130 CR + " ( -match_LANG=ABC=[a-zA-Z]* などã€?" );
131 usableProparty.put( "display", "結果を標準å?力に表示する(true)かしなã�?false)ã�? +
132 CR + "(初期値:false:表示しなã�?" );
133 usableProparty.put( "debug", "ãƒ?ƒ�ãƒ?‚°æƒ??を標準å?力に表示する(true)かしなã�?false)ã�? +
134 CR + "(初期値:false:表示しなã�?" ); // 5.7.3.0 (2014/02/07) ãƒ?ƒ�ãƒ?‚°æƒ??
135 }
136
137 /**
138 * ãƒ?ƒ•ォルトコンストラクターã€?
139 * こã?クラスは、動çš?½œæ?されますã?ãƒ?ƒ•ォルトコンストラクターでã€?
140 * super クラスに対して、å¿?¦�な初期化を行っておきますã?
141 *
142 */
143 public Process_LDAPReader() {
144 super( "org.opengion.fukurou.process.Process_LDAPReader",mustProparty,usableProparty );
145 }
146
147 /**
148 * プロセスの初期化を行いますã?初めにä¸?º¦ã�?�‘、呼び出されますã?
149 * 初期処ç�?ファイルオープンã€?¼¤?¢オープンç?に使用しますã?
150 *
151 * @og.rev 4.2.2.0 (2008/05/10) LDAP パスワード取得対å¿?
152 * @og.rev 5.3.4.0 (2011/04/01) StringUtil.nval ではなくã?getProparty の 初期値機è?を使ã�?
153 * @og.rev 5.6.7.0 (2013/07/27) REFERRAL対å¿?
154 *
155 * @param paramProcess ãƒ??タベã?スの接続å?æƒ??などを持ってã�?‚‹オブジェクãƒ?
156 */
157 public void init( final ParamProcess paramProcess ) {
158 Argument arg = getArgument();
159
160 String initctx = arg.getProparty("initctx " ,INITCTX );
161 String providerURL = arg.getProparty("providerURL" ,PROVIDER );
162 String entrydn = arg.getProparty("entrydn" ,ENTRYDN ); // 4.2.2.0 (2008/05/10)
163 String password = arg.getProparty("password" ,PASSWORD );
164 String searchbase = arg.getProparty("searchbase" ,SEARCH_BASE );
165
166 String searchScope = arg.getProparty("searchScope" ,SEARCH_SCOPE , SCOPE_LIST );
167 // timeLimit = StringUtil.nval( arg.getProparty("timeLimit") ,timeLimit );
168 // maxRowCount = StringUtil.nval( arg.getProparty("maxRowCount") ,maxRowCount );
169 timeLimit = arg.getProparty("timeLimit",timeLimit ); // 5.3.4.0 (2011/04/01)
170 maxRowCount = arg.getProparty("maxRowCount",maxRowCount ); // 5.3.4.0 (2011/04/01)
171 display = arg.getProparty("display",display);
172 debug = arg.getProparty("debug",debug); // 5.7.3.0 (2014/02/07) ãƒ?ƒ�ãƒ?‚°æƒ??
173 // if( debug ) { println( arg.toString() ); } // 5.7.3.0 (2014/02/07) ãƒ?ƒ�ãƒ?‚°æƒ??
174
175 String referral = arg.getProparty("referral",REFERRAL); // 5.6.7.0 (2013/07/27)
176
177 // 属æ?配å?を取得ã?なければゼロ配å?
178 attrs = StringUtil.csv2Array( arg.getProparty("attrs") );
179 if( attrs.length == 0 ) { attrs = null; }
180
181 // 別名定義配å?を取得ã?なければ属æ?配å?をセãƒ?ƒˆ
182 columns = StringUtil.csv2Array( arg.getProparty("columns") );
183 if( columns.length == 0 ) { columns = attrs; }
184
185 // 属æ?配å?が存在しã?属æ?定義数と別名é?列数が異なれã?エラー
186 // 以降ã?、attrs == null かã?属æ?定義数と別名é?列数が同じã?ずã?
187 if( attrs != null && attrs.length != columns.length ) {
188 String errMsg = "attrs と columns でæŒ?®šã?引数の数が異なりますã?" +
189 " attrs=[" + arg.getProparty("attrs") + "] , columns=[" +
190 arg.getProparty("columns") + "]" ;
191 throw new RuntimeException( errMsg );
192 }
193
194 // 3.8.0.9 (2005/10/17) 正規表現マッãƒ?
195 HybsEntry[] entry = arg.getEntrys( "match_" );
196 int len = entry.length;
197 matchKey = new String[columns.length]; // 正規表現
198 for( int clm=0; clm<columns.length; clm++ ) {
199 matchKey[clm] = null; // 判定チェãƒ?‚¯有無の初期åŒ?
200 for( int i=0; i<len; i++ ) {
201 if( columns[clm].equalsIgnoreCase( entry[i].getKey() ) ) {
202 matchKey[clm] = entry[i].getValue();
203 }
204 }
205 }
206
207 filter = arg.getProparty( "filter" ,filter );
208
209 Hashtable<String,String> env = new Hashtable<String,String>();
210 env.put(Context.INITIAL_CONTEXT_FACTORY, initctx);
211 env.put(Context.PROVIDER_URL, providerURL);
212 // 3.7.1.1 (2005/05/31)
213 // if( password != null && password.length() > 0 ) {
214 env.put(Context.SECURITY_CREDENTIALS, password);
215 // }
216
217 // 4.2.2.0 (2008/05/10) entrydn 属æ?の追åŠ?
218 // if( entrydn != null && entrydn.length() > 0 ) {
219 env.put(Context.SECURITY_PRINCIPAL , entrydn);
220 // }
221
222 env.put( Context.REFERRAL, referral ); // 5.6.7.0 (2013/07/27)
223
224 try {
225 DirContext ctx = new InitialDirContext(env);
226 SearchControls constraints = new SearchControls(
227 changeScopeString( searchScope ),
228 COUNT_LIMIT ,
229 timeLimit ,
230 attrs ,
231 RETURN_OBJ_FLAG ,
232 DEREF_LINK_FLAG
233 );
234
235 nameEnum = ctx.search(searchbase, filter, constraints);
236
237 } catch ( NamingException ex ) {
238 String errMsg = "NamingException !"
239 + ex.getMessage(); // 5.1.8.0 (2010/07/01) errMsg 修正
240 throw new RuntimeException( errMsg,ex );
241 }
242 }
243
244 /**
245 * プロセスの終äº?‚’行いますã?æœ?¾Œにä¸?º¦ã�?�‘、呼び出されますã?
246 * 終äº??ç�?ファイルクローズã€?¼¤?¢クローズç?に使用しますã?
247 *
248 * @param isOK トã?タルで、OKã�?�£たかどã�?�‹[true:成功/false:失敗]
249 */
250 public void end( final boolean isOK ) {
251 try {
252 if( nameEnum != null ) { nameEnum.close() ; nameEnum = null; }
253 }
254 catch ( NamingException ex ) {
255 String errMsg = "ãƒ?‚£スコネクトすることがå?来ませんã€?;
256 throw new RuntimeException( errMsg,ex );
257 }
258 }
259
260 /**
261 * こã?ãƒ??タの処ç�?�«おいて、次の処ç�?�Œ出来るかどã�?�‹を問ã�?�ˆわせますã?
262 * こã?呼び出し1回毎に、次のãƒ??タを取得する準備を行いますã?
263 *
264 * @return 処ç�?�§きる:true / 処ç�?�§きなã�?false
265 */
266 public boolean next() {
267 try {
268 return nameEnum != null && nameEnum.hasMore() ;
269 }
270 catch ( NamingException ex ) {
271 String errMsg = "ネクストすることがå?来ませんã€?;
272 throw new RuntimeException( errMsg,ex );
273 }
274 }
275
276 /**
277 * æœ??にã€?行データである LineModel を作æ?しまã�?
278 * FirstProcess は、次ã€?�¨処ç�?‚’チェインしてã�?��æœ??の行データã‚?
279 * 作æ?して、後続ã? ChainProcess クラスに処ç�?ƒ‡ータを渡しますã?
280 *
281 * @og.rev 4.2.2.0 (2008/05/10) LDAP パスワード取得対å¿?
282 *
283 * @param rowNo 処ç�?¸の行番号
284 *
285 * @return 処ç�?¤‰換後ã?LineModel
286 */
287 public LineModel makeLineModel( final int rowNo ) {
288 count++ ;
289 try {
290 if( maxRowCount > 0 && maxRowCount <= executeCount ) { return null ; }
291 SearchResult sRslt = nameEnum.next(); // 4.3.3.6 (2008/11/15) Generics警告対å¿?
292 Attributes att = sRslt.getAttributes();
293
294 if( newData == null ) {
295 newData = createLineModel( att );
296 if( display ) { println( newData.nameLine() ); }
297 }
298
299 for( int i=0; i<attrs.length; i++ ) {
300 Attribute attr = att.get(attrs[i]);
301 if( attr != null ) {
302 NamingEnumeration<?> vals = attr.getAll(); // 4.3.3.6 (2008/11/15) Generics警告対å¿?
303 StringBuilder buf = new StringBuilder();
304 // if( vals.hasMore() ) { buf.append( vals.next() ) ;}
305 if( vals.hasMore() ) { getDataChange( vals.next(),buf ) ;} // 4.2.2.0 (2008/05/10)
306 while ( vals.hasMore() ) {
307 buf.append( "," ) ;
308 // buf.append( vals.next() ) ;
309 getDataChange( vals.next(),buf ) ; // 4.2.2.0 (2008/05/10)
310 }
311 // 3.8.0.9 (2005/10/17) 正規表現マッチしなければ、スルーするã€?
312 String value = buf.toString();
313 String key = matchKey[i];
314 if( key != null && value != null && !value.matches( key ) ) {
315 return null;
316 }
317 newData.setValue( i, value );
318 executeCount++ ;
319 }
320 }
321
322 newData.setRowNo( rowNo );
323 if( display ) { println( newData.dataLine() ); }
324 }
325 catch ( NamingException ex ) {
326 String errMsg = "ãƒ??タをå?ç�?�§きませんでしたã€?" + rowNo + "]件目";
327 if( newData != null ) { errMsg += newData.toString() ; }
328 throw new RuntimeException( errMsg,ex );
329 }
330 return newData;
331 }
332
333 /**
334 * LDAPから取得したデータの変換を行いますã?
335 *
336 * 主に、バイトé?åˆ?byte[]) オブジェクトã?場合ã?æ–?—å?に戻しますã?
337 *
338 * @og.rev 4.2.2.0 (2008/05/10) 新規追åŠ?
339 *
340 * @param obj 主にバイトé?列オブジェクãƒ?
341 * @param buf å…??StringBuilder
342 *
343 * @return ãƒ??タを追åŠ?�—ã�?StringBuilder
344 */
345 private StringBuilder getDataChange( final Object obj, final StringBuilder buf ) {
346 if( obj == null ) { return buf; }
347 else if( obj instanceof byte[] ) {
348 // buf.append( new String( (byte[])obj,"ISO-8859-1" ) );
349 byte[] bb = (byte[])obj ;
350 char[] chs = new char[bb.length];
351 for( int i=0; i<bb.length; i++ ) {
352 chs[i] = (char)bb[i];
353 }
354 buf.append( chs );
355 }
356 else {
357 buf.append( obj ) ;
358 }
359
360 return buf ;
361 }
362
363 /**
364 * å†?ƒ¨で使用する LineModel を作æ?しますã?
365 * こã?クラスは、ã?ロセスチェインの基点となりますã?で、新è¦?LineModel を返しますã?
366 * Exception 以外では、å¿?�š LineModel オブジェクトを返しますã?
367 *
368 * @param att Attributesオブジェクãƒ?
369 *
370 * @return ãƒ??タベã?スから取り出して変換した LineModel
371 * @throws RuntimeException カラãƒ?��を取得できなかったå?合ã?
372 */
373 private LineModel createLineModel( final Attributes att ) {
374 LineModel model = new LineModel();
375
376 try {
377 // init() でチェãƒ?‚¯済み。attrs == null かã?属æ?定義数と別名é?列数が同じã?ずã?
378 // attrs ã�?null の場合ã?、å?キーæƒ??を取得しますã?
379 if( attrs == null ) {
380 NamingEnumeration<String> nmEnum = att.getIDs(); // 4.3.3.6 (2008/11/15) Generics警告対å¿?
381 List<String> lst = new ArrayList<String>();
382 try {
383 while( nmEnum.hasMore() ) {
384 lst.add( nmEnum.next() ); // 4.3.3.6 (2008/11/15) Generics警告対å¿?
385 }
386 }
387 finally {
388 nmEnum.close();
389 }
390 attrs = lst.toArray( new String[lst.size()] );
391 columns = attrs;
392 }
393
394 int size = columns.length;
395 model.init( size );
396 for(int clm = 0; clm < size; clm++) {
397 model.setName( clm,StringUtil.nval( columns[clm],attrs[clm] ) );
398 }
399 }
400 catch ( NamingException ex ) {
401 String errMsg = "ResultSetMetaData から、カラãƒ?��を取得できませんでしたã€?;
402 throw new RuntimeException( errMsg,ex );
403 }
404 return model;
405 }
406
407 /**
408 * スコープを表す文字å?ã‚?SearchControls の定数に変換しますã?
409 * 入力文字å?は、OBJECT、ONELEVEL、SUBTREEですã?変換する定数はã€?
410 * SearchControls クラスの static 定数ですã?
411 *
412 * @param scope スコープを表す文字å?(OBJECT、ONELEVEL、SUBTREE)
413 *
414 * @return SearchControlsの定数(OBJECT_SCOPE、ONELEVEL_SCOPE、SUBTREE_SCOPE)
415 * @see javax.naming.directory.SearchControls#OBJECT_SCOPE
416 * @see javax.naming.directory.SearchControls#ONELEVEL_SCOPE
417 * @see javax.naming.directory.SearchControls#SUBTREE_SCOPE
418 */
419 private int changeScopeString( final String scope ) {
420 int rtnScope ;
421 if( "OBJECT".equals( scope ) ) { rtnScope = SearchControls.OBJECT_SCOPE ; }
422 else if( "ONELEVEL".equals( scope ) ) { rtnScope = SearchControls.ONELEVEL_SCOPE ; }
423 else if( "SUBTREE".equals( scope ) ) { rtnScope = SearchControls.SUBTREE_SCOPE ; }
424 else {
425 String errMsg = "Search Scope in 『OBJECT』ã?ONELEVEL』ã?SUBTREE』Selected"
426 + "[" + scope + "]" ;
427 throw new RuntimeException( errMsg );
428 }
429 return rtnScope ;
430 }
431
432 /**
433 * プロセスの処ç�?µ�果のレポã?ト表現を返しますã?
434 * 処ç�??ログラãƒ?��、å?力件数、å?力件数などのæƒ??ですã?
435 * こã?æ–?—å?をそのまま、標準å?力に出すことで、結果レポã?トと出来るよã�?�ª
436 * 形式で出してくださいã€?
437 *
438 * @return 処ç�?µ�果のレポã?ãƒ?
439 */
440 public String report() {
441 String report = "[" + getClass().getName() + "]" + CR
442 + TAB + "Search Filter : " + filter + CR
443 + TAB + "Input Count : " + count ;
444
445 return report ;
446 }
447
448 /**
449 * こã?クラスの使用方法を返しますã?
450 *
451 * @return こã?クラスの使用方æ³?
452 */
453 public String usage() {
454 StringBuilder buf = new StringBuilder();
455
456 buf.append( "Process_LDAPReaderは、LDAPから読み取ったå?容をã?LineModel に設定後ã?" ).append( CR );
457 buf.append( "下流に渡すã?FirstProcess インターフェースの実è£?‚¯ラスですã?" ).append( CR );
458 buf.append( CR );
459 buf.append( "LDAPから読み取ったå?容より、LineModelを作æ?しã?下æµ?プロセスチェインはã€? ).append( CR );
460 buf.append( "チェインしてã�?‚‹ため、データは上流から下流へと渡されますã?)に渡しますã?" ).append( CR );
461 buf.append( CR );
462 buf.append( "引数æ–?—å?中に空白を含ã‚??合ã?、ダブルコーãƒ??ション(\"\") で括って下さã�??" ).append( CR );
463 buf.append( "引数æ–?—å?の ã€?』ã?前後には、空白は挟めません。å¿?�šã€?key=value の様に" ).append( CR );
464 buf.append( "繋げてくださいã€? ).append( CR );
465 buf.append( CR ).append( CR );
466
467 buf.append( getArgument().usage() ).append( CR );
468
469 return buf.toString();
470 }
471
472 /**
473 * こã?クラスは、main メソãƒ?ƒ‰から実行できませんã€?
474 *
475 * @param args コマンド引数配å?
476 */
477 public static void main( final String[] args ) {
478 LogWriter.log( new Process_LDAPReader().usage() );
479 }
480 }