OSDN Git Service

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