OSDN Git Service

version0.6.2に変更
[nt-manager/nt-manager.git] / src / twitter / manage / TweetManager.java
1 package twitter.manage;
2
3 import java.io.File;
4 import java.io.FileInputStream;
5 import java.io.FileNotFoundException;
6 import java.io.FileOutputStream;
7 import java.io.IOException;
8 import java.net.MalformedURLException;
9 import java.net.URL;
10 import java.util.ArrayList;
11 import java.util.Collection;
12 import java.util.Collections;
13 import java.util.Date;
14 import java.util.HashMap;
15 import java.util.List;
16 import java.util.Map;
17 import java.util.Properties;
18 import java.util.logging.Level;
19 import java.util.logging.Logger;
20
21 import twitter.gui.action.TweetMainAction;
22 import twitter4j.Annotations;
23 import twitter4j.DirectMessage;
24 import twitter4j.GeoLocation;
25 import twitter4j.HashtagEntity;
26 import twitter4j.IDs;
27 import twitter4j.MediaEntity;
28 import twitter4j.PagableResponseList;
29 import twitter4j.Paging;
30 import twitter4j.Place;
31 import twitter4j.Query;
32 import twitter4j.QueryResult;
33 import twitter4j.RateLimitStatus;
34 import twitter4j.ResponseList;
35 import twitter4j.Status;
36 import twitter4j.StatusUpdate;
37 import twitter4j.Tweet;
38 import twitter4j.Twitter;
39 import twitter4j.TwitterException;
40 import twitter4j.TwitterFactory;
41 import twitter4j.TwitterStream;
42 import twitter4j.TwitterStreamFactory;
43 import twitter4j.URLEntity;
44 import twitter4j.User;
45 import twitter4j.UserList;
46 import twitter4j.UserMentionEntity;
47 import twitter4j.conf.Configuration;
48 import twitter4j.conf.ConfigurationBuilder;
49 import twitter4j.auth.*;
50
51 public class TweetManager {
52
53         private Twitter twitter = null;
54         // streaming関係
55         private TweetUserStreamManager streamManager = null;
56         // クライアントのConsumer Key
57         private static final String CONSUMER_KEY = "tbo5erit2M2ZzN6n8tEYcA";
58         // クライアントのConsumer Secret 外部に漏れてはいけない
59         private static final String CONSUMER_SECRET = "tODurbdySLYU1pKjtB3MQTDRBGy562dHzVf7d62mm8";
60         // accessToken
61         private String accessToken = null;// "";
62         // secretToken 外部に漏れてはいけない
63         private String secretToken = null;// "";
64         // 設定ファイル保存ディレクトリ名
65         private static final String PROPERTIES_DIRECTORY = TweetConfiguration.PROPERTIES_DIRECTORY;
66         // 設定ファイル保存ファイル名
67         private static final String TWEET_INFO_FILENAME = TweetConfiguration.TWEET_INFO_FILENAME;
68         // アカウント情報保存ファイル名
69         private static final String ACCOUNT_INFORMATION_FILENAME = TweetConfiguration.ACCOUNT_INFORMATION_FILENAME;
70         // 一度に取得する最大のtweet数
71         private final int MAX_TWEET_NUM = 200;
72         // 前回取得したtweetの情報
73         private long sinceTweetID = 0;
74         // 前回取得したmentionのtweetID
75         private long sinceMentionID = 0;
76         // 前回取得したsendDirectMessageの情報
77         private long sinceSendDirectMessageID = 0;
78         // 前回取得したdirectMessageの情報
79         private long sinceDirectMessageID = 0;
80         // 設定ファイル
81         private Properties property = null;
82         // アカウント設定ファイル
83         private Properties accountProperty = null;
84
85         // following IDリスト keyはユーザ名, valueはユーザがfollowingしているid
86         private Map<String, List<Long>> followingUserIDList = new HashMap<String, List<Long>>();
87         // follower
88         private Map<String, List<Long>> followerUserIDList = new HashMap<String, List<Long>>();
89
90         public TweetManager() {
91         }
92
93         /**
94          * 設定ファイルを読み込む
95          *
96          * @throws IOException
97          * @throws FileNotFoundException
98          */
99         public void loadProperties() throws FileNotFoundException, IOException {
100                 if (property == null) {
101                         this.property = new Properties();
102                 }
103                 property.load(new FileInputStream("./" + PROPERTIES_DIRECTORY + "/"
104                                 + TWEET_INFO_FILENAME));
105                 // 設定読み込み
106                 String sti = this.property.getProperty("sinceTweetID");
107                 /*
108                  * String smi = this.property.getProperty("sinceMentionID"); String
109                  * ssdmi = this.property.getProperty("sinceSendDirectMessageID"); String
110                  * sdmi = this.property.getProperty("sinceDirectMessageID");
111                  */
112
113                 try {
114                         this.sinceTweetID = Long.parseLong(sti);
115                         /*
116                          * this.sinceMentionID = Long.parseLong(smi);
117                          * this.sinceSendDirectMessageID = Long.parseLong(ssdmi);
118                          * this.sinceDirectMessageID = Long.parseLong(sdmi);
119                          */
120                 } catch (NumberFormatException e) {
121                         e.printStackTrace();
122                 }
123         }
124
125         /**
126          * 設定ファイルを保存する
127          *
128          * @throws IOException
129          */
130         public void saveProperties() throws IOException {
131                 // 設定ファイルディレクトリを作成
132                 File logDir = new File("./" + PROPERTIES_DIRECTORY);
133                 if (!logDir.exists()) {
134                         // ディレクトリが存在しないので作成する
135                         if (logDir.mkdir() == false) {
136                                 throw new IOException(PROPERTIES_DIRECTORY
137                                                 + "ディレクトリを作成できませんでした.");
138                         }
139                 }
140                 if (property == null) {
141                         this.property = new Properties();
142                 }
143                 // since idを保存
144                 this.property.setProperty("sinceTweetID", sinceTweetID + "");
145                 /*
146                  * this.property.setProperty("sinceMentionID", sinceMentionID + "");
147                  * this.property.setProperty("sinceSendDirectMessageID",
148                  * sinceSendDirectMessageID + "");
149                  * this.property.setProperty("sinceDirectMessageID",
150                  * sinceDirectMessageID + "");
151                  */
152                 // プロパティのリストを保存
153                 property.store(new FileOutputStream("./" + PROPERTIES_DIRECTORY + "/"
154                                 + TWEET_INFO_FILENAME), null);
155         }
156
157         /**
158          * アカウント情報を読み込む
159          *
160          * @throws FileNotFoundException
161          * @throws IOException
162          */
163         public void loadAccountProperties() throws FileNotFoundException,
164                         IOException {
165                 if (accountProperty == null) {
166                         this.accountProperty = new Properties();
167                 }
168                 accountProperty.load(new FileInputStream("./" + PROPERTIES_DIRECTORY
169                                 + "/" + ACCOUNT_INFORMATION_FILENAME));
170                 // 設定読み込み
171                 this.accessToken = this.accountProperty.getProperty("accessToken");
172                 this.secretToken = this.accountProperty.getProperty("secretToken");
173         }
174
175         /**
176          * アカウント情報を保存する
177          *
178          * @throws IOException
179          */
180         public void saveAccountProperties() throws IOException {
181                 // 設定ファイルディレクトリを作成
182                 File logDir = new File("./" + PROPERTIES_DIRECTORY);
183                 if (!logDir.exists()) {
184                         // ディレクトリが存在しないので作成する
185                         if (logDir.mkdir() == false) {
186                                 throw new IOException(PROPERTIES_DIRECTORY
187                                                 + "ディレクトリを作成できませんでした.");
188                         }
189                 }
190                 if (accountProperty == null) {
191                         this.accountProperty = new Properties();
192                 }
193                 // since idを保存
194                 this.accountProperty.setProperty("accessToken", this.accessToken);
195                 this.accountProperty.setProperty("secretToken", this.secretToken);
196                 // プロパティのリストを保存
197                 accountProperty.store(new FileOutputStream("./" + PROPERTIES_DIRECTORY
198                                 + "/" + ACCOUNT_INFORMATION_FILENAME), null);
199         }
200
201         /**
202          * 受信したダイレクトメッセージを取得
203          *
204          * @param num
205          * @return
206          * @throws TwitterException
207          */
208         public List<Status> getDirectMessages(int num) throws TwitterException {
209                 List<DirectMessage> directMessages = twitter
210                                 .getDirectMessages(new Paging(1, num));
211                 // Tweetの一覧
212                 List<Status> messageList = new ArrayList<Status>();
213
214                 if (directMessages != null && directMessages.size() > 0) {
215                         // tweetIDを保存しておく
216                         this.sinceDirectMessageID = directMessages.get(0).getId();
217                         // 一番新しいtweetを一番したに持ってくる
218                         for (DirectMessage message : directMessages) {
219                                 User user = message.getSender();
220                                 DirectMessageUserStatus status = new DirectMessageUserStatus(
221                                                 message, user);
222                                 messageList.add(0, status);
223                         }
224                 }
225
226                 try {
227                         saveProperties();
228                 } catch (IOException e) {
229                         e.printStackTrace();
230                 }
231                 return messageList;
232         }
233
234         /**
235          * 送信したダイレクトメッセージを取得
236          *
237          * @param num
238          * @return
239          * @throws TwitterException
240          */
241         public List<Status> getSendDirectMessages(int num) throws TwitterException {
242                 List<DirectMessage> directMessages = twitter
243                                 .getSentDirectMessages(new Paging(1, num));
244                 // Tweetの一覧
245                 List<Status> messageList = new ArrayList<Status>();
246                 if (directMessages != null && directMessages.size() > 0) {
247                         // tweetIDを保存しておく
248                         this.sinceSendDirectMessageID = directMessages.get(0).getId();
249                         // 一番新しいtweetを一番したに持ってくる
250                         for (DirectMessage message : directMessages) {
251                                 User user = message.getRecipient();
252                                 DirectMessageUserStatus status = new DirectMessageUserStatus(
253                                                 message, user);
254                                 messageList.add(0, status);
255                         }
256                 }
257                 try {
258                         saveProperties();
259                 } catch (IOException e) {
260                         e.printStackTrace();
261                 }
262                 return messageList;
263         }
264
265         /**
266          * Mentionの取得
267          *
268          * @param num
269          * @return
270          * @throws TwitterException
271          */
272         public List<Status> getMentions(int num) throws TwitterException {
273                 List<Status> statuses = twitter.getMentions(new Paging(1, num));
274                 // Tweetの一覧
275                 List<Status> tweetList = new ArrayList<Status>();
276                 if (statuses != null && statuses.size() > 0) {
277                         // tweetIDを保存しておく
278                         this.sinceMentionID = statuses.get(0).getId();
279                         // 一番新しいtweetを一番したに持ってくる
280                         // for (Status status : statuses) {
281                         // tweetList.add(0, status);
282                         // }
283                         Collections.reverse(statuses);
284                         tweetList.addAll(statuses);
285                 }
286                 try {
287                         saveProperties();
288                 } catch (IOException e) {
289                         e.printStackTrace();
290                 }
291                 return tweetList;
292         }
293
294         /**
295          * まだ取得していないDirectMessageを取得
296          *
297          * @return
298          * @throws TwitterException
299          */
300         public List<Status> getNewDirectMessages() throws TwitterException {
301                 if (this.sinceDirectMessageID == 0) {
302                         return getDirectMessages(MAX_TWEET_NUM);
303                 }
304                 List<DirectMessage> directMessages = twitter
305                                 .getDirectMessages(new Paging(sinceDirectMessageID));
306                 // もし20件データ取得したらもっとデータがある可能性がある
307                 if (directMessages.size() >= 20) {
308                         List<DirectMessage> ndata = twitter.getDirectMessages(new Paging(1,
309                                         MAX_TWEET_NUM));
310                         ndata = ndata.subList(21, ndata.size());
311                         for (DirectMessage s : ndata) {
312                                 // すでに取得したことのあるデータだったとき
313                                 if (s.getId() <= sinceDirectMessageID) {
314                                         break;
315                                 }
316                                 directMessages.add(s);
317                         }
318                 }
319                 // Tweetの一覧
320                 List<Status> messageList = new ArrayList<Status>();
321                 if (directMessages != null && directMessages.size() > 0) {
322                         // tweetIDを保存しておく
323                         this.sinceDirectMessageID = directMessages.get(0).getId();
324                         // 一番新しいtweetを一番したに持ってくる
325                         for (DirectMessage message : directMessages) {
326                                 Status status = message.getSender().getStatus();
327                                 messageList.add(0, status);
328                         }
329                 }
330                 try {
331                         saveProperties();
332                 } catch (IOException e) {
333                         e.printStackTrace();
334                 }
335                 return messageList;
336         }
337
338         /**
339          * まだ取得していないSendDirectMessageを取得
340          *
341          * @return
342          * @throws TwitterException
343          */
344         public List<Status> getNewSendDirectMessages() throws TwitterException {
345                 if (this.sinceSendDirectMessageID == 0) {
346                         return getSendDirectMessages(MAX_TWEET_NUM);
347                 }
348                 List<DirectMessage> directMessages = twitter
349                                 .getDirectMessages(new Paging(sinceSendDirectMessageID));
350                 // もし20件データ取得したらもっとデータがある可能性がある
351                 if (directMessages.size() >= 20) {
352                         List<DirectMessage> ndata = twitter
353                                         .getSentDirectMessages(new Paging(1, MAX_TWEET_NUM));
354                         ndata = ndata.subList(21, ndata.size());
355                         for (DirectMessage s : ndata) {
356                                 // すでに取得したことのあるデータだったとき
357                                 if (s.getId() <= sinceSendDirectMessageID) {
358                                         break;
359                                 }
360                                 directMessages.add(s);
361                         }
362                 }
363                 // Tweetの一覧
364                 List<Status> messageList = new ArrayList<Status>();
365                 if (directMessages != null && directMessages.size() > 0) {
366                         // tweetIDを保存しておく
367                         this.sinceSendDirectMessageID = directMessages.get(0).getId();
368                         // 一番新しいtweetを一番したに持ってくる
369                         for (DirectMessage message : directMessages) {
370                                 Status status = message.getRecipient().getStatus();
371                                 messageList.add(0, status);
372                         }
373                 }
374                 try {
375                         saveProperties();
376                 } catch (IOException e) {
377                         e.printStackTrace();
378                 }
379                 return messageList;
380         }
381
382         /**
383          * まだ取得していないMention情報を取得
384          *
385          * @return
386          * @throws TwitterException
387          */
388         public List<Status> getNewMentionData() throws TwitterException {
389                 // 一度もデータを取得していないとき
390                 if (sinceMentionID == 0) {
391                         return getMentions(MAX_TWEET_NUM);
392                 }
393                 // getFriendsTimelineではRetweetは表示されないので注意
394                 List<Status> statuses = twitter.getMentions(new Paging(sinceMentionID));
395                 // もし20件データ取得したらもっとデータがある可能性がある
396                 if (statuses.size() >= 20) {
397                         List<Status> ndata = twitter.getMentions(new Paging(1,
398                                         MAX_TWEET_NUM));
399                         ndata = ndata.subList(21, ndata.size());
400                         for (Status s : ndata) {
401                                 // すでに取得したことのあるデータだったとき
402                                 if (s.getId() <= sinceMentionID) {
403                                         break;
404                                 }
405                                 statuses.add(s);
406                         }
407                 }
408
409                 // Tweetの一覧
410                 List<Status> tweetList = new ArrayList<Status>();
411                 if (statuses != null && statuses.size() > 0) {
412                         // tweetIDを保存しておく
413                         sinceMentionID = statuses.get(0).getId();
414
415                         // 一番新しいtweetを一番したに持ってくる
416                         /*
417                          * for (Status status : statuses) { tweetList.add(0, status); }
418                          */
419                         Collections.reverse(statuses);
420                         tweetList.addAll(statuses);
421                 }
422                 try {
423                         saveProperties();
424                 } catch (IOException e) {
425                         e.printStackTrace();
426                 }
427                 return tweetList;
428         }
429
430         /**
431          * まだ取得していないtweet情報を取得
432          *
433          * @return
434          * @throws TwitterException
435          */
436         public List<Status> getNewTimelineData() throws TwitterException {
437                 // 一度もデータを取得していないとき
438                 if (sinceTweetID == 0) {
439                         return getTimeline(MAX_TWEET_NUM);
440                 }
441                 // getFriendsTimelineではRetweetは表示されないので注意
442                 List<Status> statuses = twitter
443                                 .getHomeTimeline(new Paging(sinceTweetID));
444                 // もし20件データ取得したらもっとデータがある可能性がある
445                 if (statuses.size() >= 20) {
446                         List<Status> ndata = twitter.getHomeTimeline(new Paging(1,
447                                         MAX_TWEET_NUM));
448                         ndata = ndata.subList(21, ndata.size());
449                         for (Status s : ndata) {
450                                 // すでに取得したことのあるデータだったとき
451                                 if (s.getId() <= sinceTweetID) {
452                                         break;
453                                 }
454                                 statuses.add(s);
455                         }
456                 }
457                 // Tweetの一覧
458                 List<Status> tweetList = new ArrayList<Status>();
459                 if (statuses != null && statuses.size() > 0) {
460                         // tweetIDを保存しておく
461                         sinceTweetID = statuses.get(0).getId();
462
463                         // 一番新しいtweetを一番したに持ってくる
464                         /*
465                          * for (Status status : statuses) { tweetList.add(0, status); }
466                          */
467                         Collections.reverse(statuses);
468                         tweetList.addAll(statuses);
469                 }
470                 // 設定ファイル保存
471                 try {
472                         saveProperties();
473                 } catch (IOException e) {
474                         e.printStackTrace();
475                 }
476                 return tweetList;
477         }
478
479         /**
480          * タイムラインを取得 一番新しいツイートは要素の一番下に追加
481          *
482          * @param num
483          *            指定した数だけtweetを取得
484          * @return
485          * @throws TwitterException
486          */
487         public List<Status> getTimeline(int num) throws TwitterException {
488                 // getFriendsTimelineではRetweetは表示されないので注意
489                 List<Status> statuses = twitter.getHomeTimeline(new Paging(1, num));
490                 // Tweetの一覧
491                 List<Status> tweetList = new ArrayList<Status>();
492                 if (statuses != null && statuses.size() > 0) {
493                         // tweetIDを保存しておく
494                         sinceTweetID = statuses.get(0).getId();
495
496                         // 一番新しいtweetを一番したに持ってくる
497                         // for (Status status : statuses) {
498                         // tweetList.add(0, status);
499                         // }
500                         Collections.reverse(statuses);
501                         tweetList.addAll(statuses);
502                 }
503                 try {
504                         saveProperties();
505                 } catch (IOException e) {
506                         e.printStackTrace();
507                 }
508                 return tweetList;
509         }
510
511         /**
512          * 指定したワードを含むtweetを返す
513          *
514          * @param sinceID
515          * @param searchWord
516          * @return
517          */
518         public List<Status> getNewSearchResult(long sinceID, String searchWord) {
519                 // 一度もデータを取得していないとき
520                 if (sinceID == 0) {
521                         return getSearchResult(MAX_TWEET_NUM, searchWord);
522                 }
523
524                 // TODO:同じようなコードを二回書いてる.ここは修正の必要があるかも
525
526                 Query query = new Query(searchWord);
527                 // 取得するツイート最大数
528                 query.setRpp(this.MAX_TWEET_NUM);
529                 // 取得するページ番号
530                 query.setPage(1);
531                 // 追加: sinceIDを登録
532                 query.setSinceId(sinceID);
533                 // 検索結果
534                 QueryResult queryResult = null;
535                 try {
536                         queryResult = twitter.search(query);
537                 } catch (TwitterException ex) {
538                         Logger.getLogger(TweetManager.class.getName()).log(Level.SEVERE,
539                                         "Twitter searchに失敗しました", ex);
540                         ex.printStackTrace();
541                 }
542
543                 List<Status> tweetList = new ArrayList<Status>();
544
545                 if (queryResult != null) {
546                         for (Tweet tweet : queryResult.getTweets()) {
547                                 // 取得できる最大限の情報を返す
548                                 SimpleUser user = new SimpleUser();
549                                 // ユーザ名
550                                 user.setName(tweet.getFromUser());
551                                 user.setScreenName(tweet.getFromUser());
552                                 // ユーザID
553                                 user.setId(tweet.getFromUserId());
554                                 try {
555                                         // ユーザイメージ
556                                         user.setProfileImageURL(new URL(tweet.getProfileImageUrl()));
557                                 } catch (MalformedURLException ex) {
558                                         Logger.getLogger(TweetManager.class.getName()).log(
559                                                         Level.SEVERE, null, ex);
560                                 }
561
562                                 SimpleStatus status = new SimpleStatus();
563                                 status.setCreatedAt(tweet.getCreatedAt());
564                                 status.setId(tweet.getId());
565                                 status.setSource(tweet.getSource());
566                                 status.setText(tweet.getText());
567                                 status.setUser(user);
568
569                                 // 情報追加
570                                 tweetList.add(status);
571                         }
572                 }
573                 // リスト逆転 一番あたらしいtweetを一番下に
574                 Collections.reverse(tweetList);
575
576                 return tweetList;
577         }
578
579         /**
580          * 指定したワードを含むtweetを返す
581          *
582          * @param num
583          *            指定した数だけtweetを取得
584          * @param searchWord
585          *            検索したい単語
586          * @return
587          */
588         public List<Status> getSearchResult(int num, String searchWord) {
589                 Query query = new Query(searchWord);
590                 // 取得するツイート最大数
591                 query.setRpp(num);
592                 // 取得するページ番号
593                 query.setPage(1);
594                 // 検索結果
595                 QueryResult queryResult = null;
596                 try {
597                         queryResult = twitter.search(query);
598                 } catch (TwitterException ex) {
599                         Logger.getLogger(TweetManager.class.getName()).log(Level.SEVERE,
600                                         "Twitter searchに失敗しました", ex);
601                         ex.printStackTrace();
602                 }
603
604                 List<Status> tweetList = new ArrayList<Status>();
605
606                 if (queryResult != null) {
607                         for (Tweet tweet : queryResult.getTweets()) {
608                                 // 取得できる最大限の情報を返す
609                                 SimpleUser user = new SimpleUser();
610                                 // ユーザ名
611                                 user.setName(tweet.getFromUser());
612                                 user.setScreenName(tweet.getFromUser());
613                                 // ユーザID
614                                 user.setId(tweet.getFromUserId());
615                                 try {
616                                         // ユーザイメージ
617                                         user.setProfileImageURL(new URL(tweet.getProfileImageUrl()));
618                                 } catch (MalformedURLException ex) {
619                                         Logger.getLogger(TweetManager.class.getName()).log(
620                                                         Level.SEVERE, null, ex);
621                                 }
622
623                                 SimpleStatus status = new SimpleStatus();
624                                 status.setCreatedAt(tweet.getCreatedAt());
625                                 status.setId(tweet.getId());
626                                 status.setSource(tweet.getSource());
627                                 status.setText(tweet.getText());
628                                 status.setUser(user);
629
630                                 // 情報追加
631                                 tweetList.add(status);
632                         }
633                 }
634
635                 // リスト逆転 一番あたらしいtweetを一番下に
636                 Collections.reverse(tweetList);
637
638                 return tweetList;
639         }
640
641         /**
642          * 指定したユーザのお気に入りを取得
643          *
644          * @param screenName
645          *            nullの場合,自分自身のお気に入りを取得
646          */
647         public List<Status> getFavoritesTweet(String screenName)
648                         throws TwitterException {
649                 // getFriendsTimelineではRetweetは表示されないので注意
650                 List<Status> statuses = null;
651                 if (screenName == null) {
652                         // 自分自身のお気に入り取得
653                         statuses = twitter.getFavorites();
654                 } else {
655                         statuses = twitter.getFavorites(screenName);
656                 }
657                 // リスト逆転 一番あたらしいtweetを一番下に
658                 Collections.reverse(statuses);
659                 return statuses;
660         }
661
662         /**
663          * 指定したユーザの発言を取得
664          *
665          * @param num
666          * @param userID
667          * @return
668          * @throws TwitterException
669          */
670         public List<Status> getUserTimeline(int num, long userID)
671                         throws TwitterException {
672                 List<Status> statuses = twitter.getUserTimeline(userID, new Paging(1,
673                                 num));
674
675                 // tweet逆転
676                 if (statuses != null && statuses.size() > 0) {
677                         Collections.reverse(statuses);
678                 }
679
680                 return statuses;
681         }
682
683         /**
684          * 指定したユーザの発言を取得
685          *
686          * @param num
687          * @param screenName
688          * @return
689          * @throws TwitterException
690          */
691         public List<Status> getUserTimeline(int num, String screenName)
692                         throws TwitterException {
693                 List<Status> statuses = twitter.getUserTimeline(screenName, new Paging(
694                                 1, num));
695
696                 // tweet逆転
697                 if (statuses != null && statuses.size() > 0) {
698                         Collections.reverse(statuses);
699                 }
700
701                 return statuses;
702         }
703
704         /**
705          * 指定したユーザが保持しているリスト一覧を取得
706          *
707          * @param userScreenName
708          * @return
709          */
710         public List<UserList> getUserLists(String userScreenName) {
711                 List<UserList> userlist = new ArrayList<UserList>();
712                 long cursor = -1;
713                 try {
714                         for (;;) {
715                                 // ユーザリスト取得
716                                 PagableResponseList<UserList> list = this.twitter.getUserLists(
717                                                 userScreenName, cursor);
718                                 userlist.addAll(list);
719
720                                 if (list.hasNext()) {
721                                         // 次のカーソルを取得
722                                         cursor = list.getNextCursor();
723                                 } else {
724                                         break;
725                                 }
726                         }
727                 } catch (TwitterException ex) {
728                         Logger.getLogger(TweetManager.class.getName()).log(Level.SEVERE,
729                                         null, ex);
730                 }
731                 return userlist;
732         }
733
734         /**
735          * 指定したユーザをフォローしているリストを返す
736          *
737          * @param userScreenName
738          * @return
739          */
740         public List<UserList> getUserListSubscriptions(String userScreenName) {
741                 List<UserList> userlist = new ArrayList<UserList>();
742                 long cursor = -1;
743                 try {
744                         for (;;) {
745                                 // ユーザリスト取得
746                                 PagableResponseList<UserList> list = this.twitter
747                                                 .getUserListSubscriptions(userScreenName, cursor);
748                                 userlist.addAll(list);
749
750                                 if (list.hasNext()) {
751                                         // 次のカーソルを取得
752                                         cursor = list.getNextCursor();
753                                 } else {
754                                         break;
755                                 }
756                         }
757                 } catch (TwitterException ex) {
758                         Logger.getLogger(TweetManager.class.getName()).log(Level.SEVERE,
759                                         null, ex);
760                 }
761                 return userlist;
762         }
763
764         /**
765          * 指定したユーザが追加されているリストを返す
766          *
767          * @param userScreenName
768          * @return
769          */
770         public List<UserList> getUserListMemberships(String userScreenName) {
771                 List<UserList> userlist = new ArrayList<UserList>();
772                 long cursor = -1;
773                 try {
774                         for (;;) {
775                                 // ユーザリスト取得
776                                 PagableResponseList<UserList> list = this.twitter
777                                                 .getUserListMemberships(userScreenName, cursor);
778                                 userlist.addAll(list);
779
780                                 if (list.hasNext()) {
781                                         // 次のカーソルを取得
782                                         cursor = list.getNextCursor();
783                                 } else {
784                                         break;
785                                 }
786                         }
787                 } catch (TwitterException ex) {
788                         Logger.getLogger(TweetManager.class.getName()).log(Level.SEVERE,
789                                         null, ex);
790                 }
791                 return userlist;
792         }
793
794         /**
795          * 指定したリストのツイートを取得
796          *
797          * @param userScreenName
798          *            ユーザ名
799          * @param listID
800          *            リストID
801          * @param num
802          *            取得ツイート数
803          * @return
804          * @throws TwitterException
805          */
806         public List<Status> getUserListStatuses(String userScreenName, int listID,
807                         int num) {
808                 List<Status> tweetList = null;
809                 try {
810                         tweetList = this.twitter.getUserListStatuses(userScreenName,
811                                         listID, new Paging(1, num));
812                 } catch (TwitterException ex) {
813                         Logger.getLogger(TweetManager.class.getName()).log(Level.SEVERE,
814                                         null, ex);
815                 }
816                 // tweet逆転
817                 if (tweetList != null && tweetList.size() > 0) {
818                         Collections.reverse(tweetList);
819                 }
820                 return tweetList;
821         }
822
823         /**
824          * 指定したリストの最新情報を取得
825          *
826          * @param userScreenName
827          *            ユーザ名
828          * @param listID
829          *            リストID
830          * @param sinceID
831          * @return
832          */
833         public List<Status> getNewUserListStatuses(String userScreenName,
834                         int listID, long sinceID) {
835                 if (sinceID == 0) {
836                         return getUserListStatuses(userScreenName, listID, MAX_TWEET_NUM);
837                 }
838                 List<Status> tweetList = null;
839                 try {
840                         tweetList = this.twitter.getUserListStatuses(userScreenName,
841                                         listID, new Paging(sinceID));
842                 } catch (TwitterException ex) {
843                         Logger.getLogger(TweetManager.class.getName()).log(Level.SEVERE,
844                                         null, ex);
845                 }
846                 // tweet逆転
847                 if (tweetList != null && tweetList.size() > 0) {
848                         Collections.reverse(tweetList);
849                 }
850                 return tweetList;
851         }
852
853         /**
854          * 指定したユーザの最新の発言を取得
855          *
856          * @param userID
857          * @param sinceID
858          * @return
859          * @throws TwitterException
860          */
861         public List<Status> getNewUserTimeline(long userID, long sinceID)
862                         throws TwitterException {
863                 // 一度もデータを取得していないとき
864                 if (sinceID == 0) {
865                         return getUserTimeline(MAX_TWEET_NUM, userID);
866                 }
867
868                 List<Status> statuses = twitter.getUserTimeline(userID, new Paging(
869                                 sinceID));
870
871                 // tweet逆転
872                 if (statuses != null && statuses.size() > 0) {
873                         Collections.reverse(statuses);
874                 }
875
876                 return statuses;
877         }
878
879         /**
880          * 指定したユーザの最新の発言を取得
881          *
882          * @param screenName
883          * @param sinceID
884          * @return
885          * @throws TwitterException
886          */
887         public List<Status> getNewUserTimeline(String screenName, long sinceID)
888                         throws TwitterException {
889                 // 一度もデータを取得していないとき
890                 if (sinceID == 0) {
891                         return getUserTimeline(MAX_TWEET_NUM, screenName);
892                 }
893
894                 List<Status> statuses = twitter.getUserTimeline(screenName, new Paging(
895                                 sinceID));
896
897                 // tweet逆転
898                 if (statuses != null && statuses.size() > 0) {
899                         Collections.reverse(statuses);
900                 }
901
902                 return statuses;
903         }
904
905         /**
906          * Twitterへログイン
907          */
908         public void loginTwitter() throws FileNotFoundException, IOException {
909                 // アカウント情報を読み込む
910                 loadAccountProperties();
911
912                 if (this.accessToken == null || this.secretToken == null
913                                 || this.accessToken.length() < 2
914                                 || this.secretToken.length() < 2) {
915                         throw new IOException("Access Token and Secret cannot read");
916                 }
917                 // twitter
918                 twitter = new TwitterFactory().getInstance();
919                 // ConsumerKeyなどを設定
920                 twitter.setOAuthConsumer(CONSUMER_KEY, CONSUMER_SECRET);
921                 // ここにユーザのアクセストークンを入れる
922                 AccessToken ac = new AccessToken(accessToken, secretToken);
923                 twitter.setOAuthAccessToken(ac);
924
925                 // streaming用
926                 streamManager = new TweetUserStreamManager(CONSUMER_KEY,
927                                 CONSUMER_SECRET, ac, this);
928
929                 // 設定ファイルを読み込む
930                 /*
931                  * try { loadProperties(); } catch (FileNotFoundException e) {
932                  * e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); }
933                  */
934         }
935
936         /**
937          * Configurationを生成する
938          *
939          * @return
940          */
941         private Configuration getTwitterConfiguration() {
942                 ConfigurationBuilder confbuilder = new ConfigurationBuilder();
943                 confbuilder.setOAuthConsumerKey(CONSUMER_KEY);
944                 confbuilder.setOAuthConsumerSecret(CONSUMER_SECRET);
945                 return confbuilder.build();
946         }
947
948         /**
949          * 初回時アクセストークンを取得する際に利用する
950          *
951          * @param username
952          * @param password
953          * @throws TwitterException
954          */
955         public void getAccessToken(String username, String password)
956                         throws TwitterException {
957                 // consumer key secretを設定
958                 Configuration conf = this.getTwitterConfiguration();
959                 twitter = new TwitterFactory(conf).getInstance();
960                 // access token取得
961                 AccessToken oAuthAccessToken = twitter.getOAuthAccessToken(username,
962                                 password);
963                 this.accessToken = oAuthAccessToken.getToken();
964                 this.secretToken = oAuthAccessToken.getTokenSecret();
965
966                 try {
967                         // 取得したOAuthのトークンを保存
968                         saveAccountProperties();
969                 } catch (IOException ex) {
970                         ex.printStackTrace();
971                 }
972         }
973
974         /**
975          * メッセージをつぶやく
976          *
977          * @param message
978          * @throws TwitterException
979          */
980         public void tweet(String message) throws TwitterException {
981                 twitter4j.Status status;
982                 status = twitter.updateStatus(message);
983         }
984
985         /**
986          * 返信メッセージをつぶやく
987          *
988          * @param message
989          * @param replyToStatusID
990          * @throws TwitterException
991          */
992         public void replyTweet(String message, long replyToStatusID)
993                         throws TwitterException {
994                 twitter4j.Status status;
995                 // status = twitter.updateStatus(message, replyToStatusID);
996                 StatusUpdate updateMsg = new StatusUpdate(message);
997                 updateMsg.setInReplyToStatusId(replyToStatusID);
998                 status = twitter.updateStatus(updateMsg);
999         }
1000
1001         /**
1002          * ダイレクトメッセージを送信
1003          *
1004          * @param screenName
1005          * @param text
1006          * @throws TwitterException
1007          */
1008         public void sendDirectMessage(String screenName, String text)
1009                         throws TwitterException {
1010                 twitter.sendDirectMessage(screenName, text);
1011         }
1012
1013         /**
1014          * 指定したステータスIDの発言をRetweet
1015          *
1016          * @param statusID
1017          * @throws TwitterException
1018          */
1019         public void retweet(long statusID) throws TwitterException {
1020                 twitter.retweetStatus(statusID);
1021         }
1022
1023         /**
1024          * 指定した発言をお気に入りに追加
1025          *
1026          * @param statusID
1027          * @throws TwitterException
1028          */
1029         public void createFavorite(long statusID) throws TwitterException {
1030                 twitter.createFavorite(statusID);
1031         }
1032
1033         /**
1034          * 指定した発言のお気に入りを取り下げる
1035          *
1036          * @param statusID
1037          */
1038         public void destroyFavorite(long statusID) throws TwitterException {
1039                 twitter.destroyFavorite(statusID);
1040         }
1041
1042         /**
1043          * API制限数を取得
1044          *
1045          * @return
1046          * @throws TwitterException
1047          */
1048         public RateLimitStatus getRateLimitStatus() throws TwitterException {
1049                 return twitter.getRateLimitStatus();
1050         }
1051
1052         /**
1053          * 自分自身のスクリーン名を返す
1054          *
1055          * @return
1056          */
1057         public String getScreenName() {
1058                 try {
1059                         if (twitter != null) {
1060                                 return twitter.getScreenName();
1061                         }
1062                 } catch (TwitterException e) {
1063
1064                 }
1065                 return null;
1066         }
1067
1068         /**
1069          * 指定したユーザのfollowingユーザ一覧の詳細情報を取得
1070          *
1071          * @param screenName
1072          *            取得したいユーザ
1073          * @param page
1074          *            ページ1あたり100件の情報を取得
1075          * @return
1076          */
1077         public List<User> getFollowingUser(String screenName, int page) {
1078                 if (!this.followingUserIDList.containsKey(screenName)) {
1079                         // まだscreenNameがfollowingしているユーザ情報を取得していない
1080                         List<Long> following = this.getFollowingUserID(screenName);
1081                         this.followingUserIDList.put(screenName, following);
1082                 }
1083                 // followingユーザ一覧id取得
1084                 List<Long> getFollowingUserIds = null;
1085                 List<Long> followingList = this.followingUserIDList.get(screenName);
1086                 if (followingList != null && followingList.size() > 0) {
1087                         // データ存在しない
1088                         if (followingList.size() < page * 100) {
1089                                 return null;
1090                         }
1091                         int to = page * 100 + 99;
1092                         if (followingList.size() < to) {
1093                                 to = to - (to - followingList.size());
1094                         }
1095                         getFollowingUserIds = followingList.subList(page * 100, to);
1096                 }
1097
1098                 // 結果
1099                 List<User> result = new ArrayList<User>();
1100
1101                 int getDataSize = getFollowingUserIds.size();
1102                 if (getDataSize > 0) {
1103                         long[] ids = new long[getDataSize];
1104                         for (int i = 0; i < ids.length; i++) {
1105                                 ids[i] = getFollowingUserIds.get(i);
1106                         }
1107
1108                         // idsのユーザ一覧取得
1109                         try {
1110                                 ResponseList<User> users = twitter.lookupUsers(ids);
1111                                 for (User u : users) {
1112                                         result.add(u);
1113                                 }
1114                         } catch (TwitterException e) {
1115                                 e.printStackTrace();
1116                         }
1117
1118                 }
1119                 return result;
1120         }
1121
1122         /**
1123          * 指定したユーザのfollowerユーザ一覧の詳細情報を取得
1124          *
1125          * @param screenName
1126          *            取得したいユーザ
1127          * @param page
1128          *            ページ1あたり100件の情報を取得
1129          * @return
1130          */
1131         public List<User> getFollowerUser(String screenName, int page) {
1132                 if (!this.followerUserIDList.containsKey(screenName)) {
1133                         // まだscreenNameがfollowingしているユーザ情報を取得していない
1134                         List<Long> follower = this.getFollowerUserID(screenName);
1135                         this.followerUserIDList.put(screenName, follower);
1136                 }
1137                 // followingユーザ一覧id取得
1138                 List<Long> getFollowerUserIds = null;
1139                 List<Long> followerList = this.followerUserIDList.get(screenName);
1140                 if (followerList != null && followerList.size() > 0) {
1141                         // データ存在しない
1142                         if (followerList.size() < page * 100) {
1143                                 return null;
1144                         }
1145                         int to = page * 100 + 99;
1146                         if (followerList.size() < to) {
1147                                 to = to - (to - followerList.size());
1148                         }
1149                         getFollowerUserIds = followerList.subList(page * 100, to);
1150                 }
1151
1152                 // 結果
1153                 List<User> result = new ArrayList<User>();
1154
1155                 int getDataSize = getFollowerUserIds.size();
1156                 if (getDataSize > 0) {
1157                         long[] ids = new long[getDataSize];
1158                         for (int i = 0; i < ids.length; i++) {
1159                                 ids[i] = getFollowerUserIds.get(i);
1160                         }
1161
1162                         // idsのユーザ一覧取得
1163                         try {
1164                                 ResponseList<User> users = twitter.lookupUsers(ids);
1165                                 for (User u : users) {
1166                                         result.add(u);
1167                                 }
1168                         } catch (TwitterException e) {
1169                                 e.printStackTrace();
1170                         }
1171
1172                 }
1173                 return result;
1174         }
1175
1176         /**
1177          * FriendのID一覧を取得する
1178          *
1179          * @param screenName
1180          * @return
1181          */
1182         public List<Long> getFollowingUserID(String screenName) {
1183                 long cursor = -1;
1184                 IDs ids = null;
1185                 long[] friendIds = null;
1186                 // id一覧
1187                 List<Long> result = new ArrayList<Long>();
1188
1189                 try {
1190                         // friend一覧をすべて取得
1191                         do {
1192                                 ids = twitter.getFriendsIDs(screenName, cursor);
1193                                 // screenNameのフレンドid一覧を取得
1194                                 friendIds = ids.getIDs();
1195                                 if (friendIds.length > 0) {
1196                                         for (long id : friendIds) {
1197                                                 result.add(id);
1198                                         }
1199                                 }
1200                                 // 次のカーソルに移動
1201                                 cursor = ids.getNextCursor();
1202                         } while (cursor != 0);
1203
1204                 } catch (TwitterException e) {
1205                         e.printStackTrace();
1206                 }
1207                 return result;
1208         }
1209
1210         /**
1211          * Friendのfollewer ID一覧を取得する
1212          *
1213          * @param screenName
1214          * @return
1215          */
1216         public List<Long> getFollowerUserID(String screenName) {
1217                 long cursor = -1;
1218                 IDs ids = null;
1219                 long[] friendIds = null;
1220                 // id一覧
1221                 List<Long> result = new ArrayList<Long>();
1222
1223                 try {
1224                         // friend一覧をすべて取得
1225                         do {
1226                                 ids = twitter.getFollowersIDs(screenName, cursor);
1227                                 // screenNameのフレンドid一覧を取得
1228                                 friendIds = ids.getIDs();
1229                                 if (friendIds.length > 0) {
1230                                         for (long id : friendIds) {
1231                                                 result.add(id);
1232                                         }
1233                                 }
1234                                 // 次のカーソルに移動
1235                                 cursor = ids.getNextCursor();
1236                         } while (cursor != 0);
1237
1238                 } catch (TwitterException e) {
1239                         e.printStackTrace();
1240                 }
1241                 return result;
1242         }
1243
1244         /**
1245          * streamManagerを取得します。
1246          * @return streamManager
1247          */
1248         public TweetUserStreamManager getStreamManager() {
1249             return streamManager;
1250         }
1251
1252         /**
1253          * sinceTweetIDを取得します。
1254          *
1255          * @return sinceTweetID
1256          */
1257         public long getSinceTweetID() {
1258                 return sinceTweetID;
1259         }
1260
1261         /**
1262          * sinceTweetIDを設定します。
1263          *
1264          * @param sinceTweetID
1265          *            sinceTweetID
1266          */
1267         public void setSinceTweetID(long sinceTweetID) {
1268                 this.sinceTweetID = sinceTweetID;
1269         }
1270
1271         /**
1272          * sinceMentionIDを取得します。
1273          *
1274          * @return sinceMentionID
1275          */
1276         public long getSinceMentionID() {
1277                 return sinceMentionID;
1278         }
1279
1280         /**
1281          * sinceMentionIDを設定します。
1282          *
1283          * @param sinceMentionID
1284          *            sinceMentionID
1285          */
1286         public void setSinceMentionID(long sinceMentionID) {
1287                 this.sinceMentionID = sinceMentionID;
1288         }
1289
1290         /**
1291          * sinceSendDirectMessageIDを取得します。
1292          *
1293          * @return sinceSendDirectMessageID
1294          */
1295         public long getSinceSendDirectMessageID() {
1296                 return sinceSendDirectMessageID;
1297         }
1298
1299         /**
1300          * sinceSendDirectMessageIDを設定します。
1301          *
1302          * @param sinceSendDirectMessageID
1303          *            sinceSendDirectMessageID
1304          */
1305         public void setSinceSendDirectMessageID(long sinceSendDirectMessageID) {
1306                 this.sinceSendDirectMessageID = sinceSendDirectMessageID;
1307         }
1308
1309         /**
1310          * sinceDirectMessageIDを取得します。
1311          *
1312          * @return sinceDirectMessageID
1313          */
1314         public long getSinceDirectMessageID() {
1315                 return sinceDirectMessageID;
1316         }
1317
1318         /**
1319          * sinceDirectMessageIDを設定します。
1320          *
1321          * @param sinceDirectMessageID
1322          *            sinceDirectMessageID
1323          */
1324         public void setSinceDirectMessageID(long sinceDirectMessageID) {
1325                 this.sinceDirectMessageID = sinceDirectMessageID;
1326         }
1327
1328         /**
1329          * ログインユーザのIDを取得
1330          * @return 取得失敗時は0を返す
1331          */
1332         public long getLoginUserID() {
1333                 long id = 0;
1334                 try {
1335                         id = this.twitter.getId();
1336                 } catch (IllegalStateException e) {
1337                         e.printStackTrace();
1338                 } catch (TwitterException e) {
1339                         e.printStackTrace();
1340                 }
1341                 return id;
1342         }
1343
1344         /**
1345          * ログインユーザのスクリーン名を取得
1346          * @return
1347          */
1348         public String getLoginUserScreenName() {
1349                 String username = null;
1350                 try {
1351                         username = this.twitter.getScreenName();
1352                 } catch (IllegalStateException e) {
1353                         e.printStackTrace();
1354                 } catch (TwitterException e) {
1355                         e.printStackTrace();
1356                 }
1357                 return username;
1358         }
1359
1360         /**
1361          * 指定したユーザ名からユーザidを取得する
1362          * @param screenName
1363          * @return 取得に失敗した場合は0を返す, 成功した場合はユーザidを返す
1364          */
1365         public long getUserID(String screenName) {
1366                 long id = 0;
1367                 try {
1368                         User u = this.twitter.showUser(screenName);
1369                         if( u != null ) {
1370                                 id = u.getId();
1371                         }
1372                 } catch (TwitterException e) {
1373                         e.printStackTrace();
1374                 }
1375                 return id;
1376         }
1377
1378 }