OSDN Git Service

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