diff --git a/sandbox/twitter/.gitignore b/sandbox/twitter/.gitignore new file mode 100644 index 0000000000..0432445082 --- /dev/null +++ b/sandbox/twitter/.gitignore @@ -0,0 +1,9 @@ +# use glob syntax. +syntax: glob +target +.settings +.classpath +.project +jclouds-twitter.iml +jclouds-twitter.ipr +jclouds-twitter.iws \ No newline at end of file diff --git a/sandbox/twitter/README.txt b/sandbox/twitter/README.txt new file mode 100644 index 0000000000..b2401ed4a6 --- /dev/null +++ b/sandbox/twitter/README.txt @@ -0,0 +1,24 @@ +==== + + Copyright (C) 2010 Cloud Conscious, LLC. + + ==================================================================== + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + ==================================================================== +==== +# +# The jclouds provider for Twitter (http://twitter.com/). +# +# TODO: Implementation status. +# TODO: Supported features. +# TODO: Usage example. diff --git a/sandbox/twitter/pom.xml b/sandbox/twitter/pom.xml new file mode 100644 index 0000000000..dd0bd6abb6 --- /dev/null +++ b/sandbox/twitter/pom.xml @@ -0,0 +1,128 @@ + + + + 4.0.0 + + org.jclouds + jclouds-project + 1.0-SNAPSHOT + ../../project/pom.xml + + org.jclouds + jclouds-twitter + jclouds twitter core + jclouds components to access twitter + + + + + jclouds-googlecode-deploy + http://jclouds.googlecode.com/svn/repo + + + jclouds-rimu-snapshots-nexus + https://oss.sonatype.org/content/repositories/snapshots + + true + + + + + + + http://api.twitter.com + 1.0 + FIXME + FIXME + + + + ${project.groupId} + jclouds-core + ${project.version} + + + ${project.groupId} + jclouds-core + ${project.version} + test-jar + test + + + log4j + log4j + 1.2.14 + test + + + ${project.groupId} + jclouds-log4j + ${project.version} + test + + + + + live + + + + org.apache.maven.plugins + maven-surefire-plugin + + + integration + integration-test + + test + + + + + test.twitter.endpoint + ${test.twitter.endpoint} + + + test.twitter.apiversion + ${test.twitter.apiversion} + + + test.twitter.identity + ${test.twitter.identity} + + + test.twitter.credential + ${test.twitter.credential} + + + + + + + + + + + diff --git a/sandbox/twitter/src/main/java/org/jclouds/twitter/Twitter.java b/sandbox/twitter/src/main/java/org/jclouds/twitter/Twitter.java new file mode 100644 index 0000000000..507f89131a --- /dev/null +++ b/sandbox/twitter/src/main/java/org/jclouds/twitter/Twitter.java @@ -0,0 +1,39 @@ +/** + * + * Copyright (C) 2009 Cloud Conscious, LLC. + * + * ==================================================================== + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ==================================================================== + */ +package org.jclouds.twitter; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +import javax.inject.Qualifier; + +/** + * Related to a Twitter resource. + * + * @author Adrian Cole + * + */ +@Retention(value = RetentionPolicy.RUNTIME) +@Target(value = { ElementType.FIELD, ElementType.PARAMETER, ElementType.METHOD }) +@Qualifier +public @interface Twitter { + +} \ No newline at end of file diff --git a/sandbox/twitter/src/main/java/org/jclouds/twitter/TwitterAsyncClient.java b/sandbox/twitter/src/main/java/org/jclouds/twitter/TwitterAsyncClient.java new file mode 100644 index 0000000000..3250396fe6 --- /dev/null +++ b/sandbox/twitter/src/main/java/org/jclouds/twitter/TwitterAsyncClient.java @@ -0,0 +1,53 @@ +/** + * + * Copyright (C) 2009 Cloud Conscious, LLC. + * + * ==================================================================== + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ==================================================================== + */ +package org.jclouds.twitter; + +import java.util.SortedSet; + +import javax.ws.rs.Consumes; +import javax.ws.rs.GET; +import javax.ws.rs.Path; +import javax.ws.rs.core.MediaType; + +import org.jclouds.http.filters.BasicAuthentication; +import org.jclouds.rest.annotations.RequestFilters; +import org.jclouds.twitter.domain.Status; + +import com.google.common.util.concurrent.ListenableFuture; + +/** + * Provides asynchronous access to Twitter via their REST API. + *

+ * + * @see TwitterClient + * @see + * @author Adrian Cole + */ +@RequestFilters(BasicAuthentication.class) +public interface TwitterAsyncClient { + + /** + * @see TwitterClient#getMyMentions() + */ + @GET + @Consumes(MediaType.APPLICATION_JSON) + @Path("/statuses/mentions.json") + ListenableFuture> getMyMentions(); + +} diff --git a/sandbox/twitter/src/main/java/org/jclouds/twitter/TwitterClient.java b/sandbox/twitter/src/main/java/org/jclouds/twitter/TwitterClient.java new file mode 100644 index 0000000000..a3c050c9c3 --- /dev/null +++ b/sandbox/twitter/src/main/java/org/jclouds/twitter/TwitterClient.java @@ -0,0 +1,40 @@ +/** + * + * Copyright (C) 2009 Cloud Conscious, LLC. + * + * ==================================================================== + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ==================================================================== + */ +package org.jclouds.twitter; + +import java.util.SortedSet; +import java.util.concurrent.TimeUnit; + +import org.jclouds.concurrent.Timeout; +import org.jclouds.twitter.domain.Status; + +/** + * Provides access to Twitter via their REST API. + *

+ * + * @see + * @see TwitterAsyncClient + * @author Adrian Cole + */ +@Timeout(duration = 4, timeUnit = TimeUnit.SECONDS) +public interface TwitterClient { + + SortedSet getMyMentions(); + +} diff --git a/sandbox/twitter/src/main/java/org/jclouds/twitter/TwitterContextBuilder.java b/sandbox/twitter/src/main/java/org/jclouds/twitter/TwitterContextBuilder.java new file mode 100755 index 0000000000..df597d6ddc --- /dev/null +++ b/sandbox/twitter/src/main/java/org/jclouds/twitter/TwitterContextBuilder.java @@ -0,0 +1,45 @@ +/** + * + * Copyright (C) 2010 Cloud Conscious, LLC. + * + * ==================================================================== + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ==================================================================== + */ + +package org.jclouds.twitter; + +import java.util.List; +import java.util.Properties; + +import org.jclouds.rest.RestContextBuilder; +import org.jclouds.twitter.config.TwitterRestClientModule; + +import com.google.inject.Module; + +/** + * + * @author Adrian Cole + */ +public class TwitterContextBuilder extends + RestContextBuilder { + + public TwitterContextBuilder(Properties props) { + super(TwitterClient.class, TwitterAsyncClient.class, props); + } + + protected void addClientModule(List modules) { + modules.add(new TwitterRestClientModule()); + } + +} diff --git a/sandbox/twitter/src/main/java/org/jclouds/twitter/TwitterPropertiesBuilder.java b/sandbox/twitter/src/main/java/org/jclouds/twitter/TwitterPropertiesBuilder.java new file mode 100644 index 0000000000..ea1411783e --- /dev/null +++ b/sandbox/twitter/src/main/java/org/jclouds/twitter/TwitterPropertiesBuilder.java @@ -0,0 +1,47 @@ +/** + * + * Copyright (C) 2010 Cloud Conscious, LLC. + * + * ==================================================================== + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ==================================================================== + */ + +package org.jclouds.twitter; + +import static org.jclouds.Constants.PROPERTY_API_VERSION; +import static org.jclouds.Constants.PROPERTY_ENDPOINT; + +import java.util.Properties; + +import org.jclouds.PropertiesBuilder; + +/** + * Builds properties used in twitter Clients + * + * @author Adrian Cole + */ +public class TwitterPropertiesBuilder extends PropertiesBuilder { + @Override + protected Properties defaultProperties() { + Properties properties = super.defaultProperties(); + properties.setProperty(PROPERTY_ENDPOINT, "https://api.twitter.com"); + properties.setProperty(PROPERTY_API_VERSION, "1.0"); + return properties; + } + + public TwitterPropertiesBuilder(Properties properties) { + super(properties); + } + +} diff --git a/sandbox/twitter/src/main/java/org/jclouds/twitter/config/TwitterRestClientModule.java b/sandbox/twitter/src/main/java/org/jclouds/twitter/config/TwitterRestClientModule.java new file mode 100755 index 0000000000..be0790d5cd --- /dev/null +++ b/sandbox/twitter/src/main/java/org/jclouds/twitter/config/TwitterRestClientModule.java @@ -0,0 +1,61 @@ +/** + * + * Copyright (C) 2010 Cloud Conscious, LLC. + * + * ==================================================================== + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ==================================================================== + */ + +package org.jclouds.twitter.config; + +import org.jclouds.http.RequiresHttp; +import org.jclouds.json.config.GsonModule.CDateAdapter; +import org.jclouds.json.config.GsonModule.DateAdapter; +import org.jclouds.rest.ConfiguresRestClient; +import org.jclouds.rest.config.RestClientModule; +import org.jclouds.twitter.TwitterAsyncClient; +import org.jclouds.twitter.TwitterClient; + +/** + * Configures the twitter connection. + * + * @author Adrian Cole + */ +@RequiresHttp +@ConfiguresRestClient +public class TwitterRestClientModule extends RestClientModule { + + public TwitterRestClientModule() { + super(TwitterClient.class, TwitterAsyncClient.class); + } + + @Override + protected void configure() { + super.configure(); + bind(DateAdapter.class).to(CDateAdapter.class); + } + + @Override + protected void bindErrorHandlers() { +// bind(HttpErrorHandler.class).annotatedWith(Redirection.class).to(TwitterErrorHandler.class); +// bind(HttpErrorHandler.class).annotatedWith(ClientError.class).to(TwitterErrorHandler.class); +// bind(HttpErrorHandler.class).annotatedWith(ServerError.class).to(TwitterErrorHandler.class); + } + + @Override + protected void bindRetryHandlers() { + // TODO + } + +} diff --git a/sandbox/twitter/src/main/java/org/jclouds/twitter/domain/Status.java b/sandbox/twitter/src/main/java/org/jclouds/twitter/domain/Status.java new file mode 100644 index 0000000000..ffecb0e454 --- /dev/null +++ b/sandbox/twitter/src/main/java/org/jclouds/twitter/domain/Status.java @@ -0,0 +1,197 @@ +/** + * + * Copyright (C) 2009 Cloud Conscious, LLC. + * + * ==================================================================== + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ==================================================================== + */ +package org.jclouds.twitter.domain; + +import java.util.Date; + +import com.google.gson.annotations.SerializedName; + +/** + * + * @author Adrian Cole + * + */ +public class Status implements Comparable { + @SerializedName("created_at") + private Date createdAt; + private boolean favorited; + private String geo; + private long id; + @SerializedName("in_reply_to_screen_name") + private String inReplyToScreenName; + @SerializedName("in_reply_to_status_id") + private Integer inReplyToStatusId; + @SerializedName("in_reply_to_user_id") + private Integer inReplyToUserId; + private String source; + private String text; + private boolean truncated; + private User user; + + public Status() { + } + + public Status(Date createdAt, boolean favorited, String geo, long id, + String inReplyToScreenName, Integer inReplyToStatusId, Integer inReplyToUserId, + String source, String text, boolean truncated, User user) { + this.createdAt = createdAt; + this.favorited = favorited; + this.geo = geo; + this.id = id; + this.inReplyToScreenName = inReplyToScreenName; + this.inReplyToStatusId = inReplyToStatusId; + this.inReplyToUserId = inReplyToUserId; + this.source = source; + this.text = text; + this.truncated = truncated; + this.user = user; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((createdAt == null) ? 0 : createdAt.hashCode()); + result = prime * result + (int) (id ^ (id >>> 32)); + result = prime * result + ((text == null) ? 0 : text.hashCode()); + result = prime * result + ((user == null) ? 0 : user.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + Status other = (Status) obj; + if (createdAt == null) { + if (other.createdAt != null) + return false; + } else if (!createdAt.equals(other.createdAt)) + return false; + if (id != other.id) + return false; + if (text == null) { + if (other.text != null) + return false; + } else if (!text.equals(other.text)) + return false; + if (user == null) { + if (other.user != null) + return false; + } else if (!user.equals(other.user)) + return false; + return true; + } + + public Date getCreatedAt() { + return createdAt; + } + + public void setCreatedAt(Date createdAt) { + this.createdAt = createdAt; + } + + public long getId() { + return id; + } + + public void setId(long id) { + this.id = id; + } + + public String getText() { + return text; + } + + public void setText(String text) { + this.text = text; + } + + public String getSource() { + return source; + } + + public void setSource(String source) { + this.source = source; + } + + public boolean isTruncated() { + return truncated; + } + + public void setTruncated(boolean truncated) { + this.truncated = truncated; + } + + public Integer getInReplyToStatusId() { + return inReplyToStatusId; + } + + public void setInReplyToStatusId(Integer inReplyToStatusId) { + this.inReplyToStatusId = inReplyToStatusId; + } + + public Integer getInReplyToUserId() { + return inReplyToUserId; + } + + public void setInReplyToUserId(Integer inReplyToUserId) { + this.inReplyToUserId = inReplyToUserId; + } + + public boolean isFavorited() { + return favorited; + } + + public void setFavorited(boolean favorited) { + this.favorited = favorited; + } + + public String getInReplyToScreenName() { + return inReplyToScreenName; + } + + public void setInReplyToScreenName(String inReplyToScreenName) { + this.inReplyToScreenName = inReplyToScreenName; + } + + public User getUser() { + return user; + } + + public void setUser(User user) { + this.user = user; + } + + public int compareTo(Status o) { + return (int) ((this == o) ? 0 : id + "".compareTo(o.id + "")); + } + + public void setGeo(String geo) { + this.geo = geo; + } + + public String getGeo() { + return geo; + } +} \ No newline at end of file diff --git a/sandbox/twitter/src/main/java/org/jclouds/twitter/domain/User.java b/sandbox/twitter/src/main/java/org/jclouds/twitter/domain/User.java new file mode 100644 index 0000000000..a93ece3bb5 --- /dev/null +++ b/sandbox/twitter/src/main/java/org/jclouds/twitter/domain/User.java @@ -0,0 +1,363 @@ +/** + * + * Copyright (C) 2009 Cloud Conscious, LLC. + * + * ==================================================================== + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ==================================================================== + */ +package org.jclouds.twitter.domain; + +import java.net.URI; +import java.util.Date; + +import com.google.gson.annotations.SerializedName; + +/** + * + * @author Adrian Cole + */ +public class User implements Comparable { + @SerializedName("created_at") + private Date createdAt; + private String description; + @SerializedName("favourites_count") + private int favouritesCount; + @SerializedName("followers_count") + private int followersCount; + private boolean following; + @SerializedName("friends_count") + private int friendsCount; + @SerializedName("geo_enabled") + private boolean geoEnabled; + private long id; + private String location; + private String name; + private boolean notifications; + @SerializedName("profile_background_color") + private String profileBackgroundColor; + @SerializedName("profile_background_image_url") + private URI profileBackgroundImageUrl; + @SerializedName("profile_background_tile") + private boolean profileBackgroundTile; + @SerializedName("profile_image_url") + private URI profileImageUrl; + @SerializedName("profile_link_color") + private String profileLinkColor; + @SerializedName("profile_sidebar_border_color") + private String profileSidebarBorderColor; + @SerializedName("profile_sidebar_fill_color") + private String profileSidebarFillColor; + @SerializedName("profile_text_color") + private String profileTextColor; + @SerializedName("protected") + private boolean isProtected; + @SerializedName("screen_name") + private String screenName; + @SerializedName("statuses_count") + private int statusesCount; + @SerializedName("time_zone") + private String timeZone; + private URI url; + @SerializedName("utc_offset") + private int utcOffset; + private boolean verified; + + public User() { + + } + + public User(Date createdAt, String description, int favouritesCount, int followersCount, + boolean following, int friendsCount, boolean geoEnabled, long id, String location, + String name, boolean notifications, String profileBackgroundColor, + URI profileBackgroundImageUrl, boolean profileBackgroundTile, URI profileImageUrl, + String profileLinkColor, String profileSidebarBorderColor, + String profileSidebarFillColor, String profileTextColor, boolean isProtected, + String screenName, int statusesCount, String timeZone, URI url, int utcOffset, + boolean verified) { + this.createdAt = createdAt; + this.description = description; + this.favouritesCount = favouritesCount; + this.followersCount = followersCount; + this.following = following; + this.friendsCount = friendsCount; + this.setGeoEnabled(geoEnabled); + this.id = id; + this.location = location; + this.name = name; + this.notifications = notifications; + this.profileBackgroundColor = profileBackgroundColor; + this.profileBackgroundImageUrl = profileBackgroundImageUrl; + this.profileBackgroundTile = profileBackgroundTile; + this.profileImageUrl = profileImageUrl; + this.profileLinkColor = profileLinkColor; + this.profileSidebarBorderColor = profileSidebarBorderColor; + this.profileSidebarFillColor = profileSidebarFillColor; + this.profileTextColor = profileTextColor; + this.isProtected = isProtected; + this.screenName = screenName; + this.statusesCount = statusesCount; + this.timeZone = timeZone; + this.url = url; + this.utcOffset = utcOffset; + this.verified = verified; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + (int) (id ^ (id >>> 32)); + result = prime * result + ((name == null) ? 0 : name.hashCode()); + result = prime * result + ((screenName == null) ? 0 : screenName.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + User other = (User) obj; + if (id != other.id) + return false; + if (name == null) { + if (other.name != null) + return false; + } else if (!name.equals(other.name)) + return false; + if (screenName == null) { + if (other.screenName != null) + return false; + } else if (!screenName.equals(other.screenName)) + return false; + return true; + } + + public long getId() { + return id; + } + + public void setId(long id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getScreenName() { + return screenName; + } + + public void setScreenName(String screenName) { + this.screenName = screenName; + } + + public String getLocation() { + return location; + } + + public void setLocation(String location) { + this.location = location; + } + + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } + + public URI getProfileImageUrl() { + return profileImageUrl; + } + + public void setProfileImageUrl(URI profileImageUrl) { + this.profileImageUrl = profileImageUrl; + } + + public URI getUrl() { + return url; + } + + public void setUrl(URI url) { + this.url = url; + } + + public boolean isProtected() { + return isProtected; + } + + public void setProtected(boolean isProtected) { + this.isProtected = isProtected; + } + + public int getFollowersCount() { + return followersCount; + } + + public void setFollowersCount(int followersCount) { + this.followersCount = followersCount; + } + + public String getProfileBackgroundColor() { + return profileBackgroundColor; + } + + public void setProfileBackgroundColor(String profileBackgroundColor) { + this.profileBackgroundColor = profileBackgroundColor; + } + + public String getProfileTextColor() { + return profileTextColor; + } + + public void setProfileTextColor(String profileTextColor) { + this.profileTextColor = profileTextColor; + } + + public String getProfileLinkColor() { + return profileLinkColor; + } + + public void setProfileLinkColor(String profileLinkColor) { + this.profileLinkColor = profileLinkColor; + } + + public String getProfileSidebarFillColor() { + return profileSidebarFillColor; + } + + public void setProfileSidebarFillColor(String profileSidebarFillColor) { + this.profileSidebarFillColor = profileSidebarFillColor; + } + + public String getProfileSidebarBorderColor() { + return profileSidebarBorderColor; + } + + public void setProfileSidebarBorderColor(String profileSidebarBorderColor) { + this.profileSidebarBorderColor = profileSidebarBorderColor; + } + + public int getFriendsCount() { + return friendsCount; + } + + public void setFriendsCount(int friendsCount) { + this.friendsCount = friendsCount; + } + + public Date getCreatedAt() { + return createdAt; + } + + public void setCreatedAt(Date createdAt) { + this.createdAt = createdAt; + } + + public int getFavouritesCount() { + return favouritesCount; + } + + public void setFavouritesCount(int favouritesCount) { + this.favouritesCount = favouritesCount; + } + + public int getUtcOffset() { + return utcOffset; + } + + public void setUtcOffset(int utcOffset) { + this.utcOffset = utcOffset; + } + + public String getTimeZone() { + return timeZone; + } + + public void setTimeZone(String timeZone) { + this.timeZone = timeZone; + } + + public URI getProfileBackgroundImageUrl() { + return profileBackgroundImageUrl; + } + + public void setProfileBackgroundImageUrl(URI profileBackgroundImageUrl) { + this.profileBackgroundImageUrl = profileBackgroundImageUrl; + } + + public boolean isProfileBackgroundTile() { + return profileBackgroundTile; + } + + public void setProfileBackgroundTile(boolean profileBackgroundTile) { + this.profileBackgroundTile = profileBackgroundTile; + } + + public int getStatusesCount() { + return statusesCount; + } + + public void setStatusesCount(int statusesCount) { + this.statusesCount = statusesCount; + } + + public boolean isNotifications() { + return notifications; + } + + public void setNotifications(boolean notifications) { + this.notifications = notifications; + } + + public boolean isFollowing() { + return following; + } + + public void setFollowing(boolean following) { + this.following = following; + } + + public boolean isVerified() { + return verified; + } + + public void setVerified(boolean verified) { + this.verified = verified; + } + + public int compareTo(User o) { + if (screenName == null) + return -1; + return (this == o) ? 0 : screenName.compareTo(o.screenName); + } + + public void setGeoEnabled(boolean geoEnabled) { + this.geoEnabled = geoEnabled; + } + + public boolean isGeoEnabled() { + return geoEnabled; + } +} \ No newline at end of file diff --git a/sandbox/twitter/src/test/java/org/jclouds/twitter/TwitterAsyncClientTest.java b/sandbox/twitter/src/test/java/org/jclouds/twitter/TwitterAsyncClientTest.java new file mode 100644 index 0000000000..87f0fc8892 --- /dev/null +++ b/sandbox/twitter/src/test/java/org/jclouds/twitter/TwitterAsyncClientTest.java @@ -0,0 +1,113 @@ +/** + * + * Copyright (C) 2010 Cloud Conscious, LLC. + * + * ==================================================================== + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ==================================================================== + */ + +package org.jclouds.twitter; + +import static org.testng.Assert.assertEquals; + +import java.io.IOException; +import java.lang.reflect.Method; +import java.util.Properties; + +import org.jclouds.http.HttpRequest; +import org.jclouds.http.RequiresHttp; +import org.jclouds.http.filters.BasicAuthentication; +import org.jclouds.http.functions.ParseJson; +import org.jclouds.rest.ConfiguresRestClient; +import org.jclouds.rest.RestClientTest; +import org.jclouds.rest.RestContextFactory; +import org.jclouds.rest.RestContextSpec; +import org.jclouds.rest.internal.GeneratedHttpRequest; +import org.jclouds.rest.internal.RestAnnotationProcessor; +import org.jclouds.twitter.config.TwitterRestClientModule; +import org.testng.annotations.Test; + +import com.google.common.collect.Iterables; +import com.google.inject.Module; +import com.google.inject.TypeLiteral; + +/** + * Tests annotation parsing of {@code TwitterAsyncClient} + * + * @author Adrian Cole + */ +@Test(groups = "unit") +public class TwitterAsyncClientTest extends RestClientTest { + public void testGetMyMentions() throws SecurityException, NoSuchMethodException, IOException { + Method method = TwitterAsyncClient.class.getMethod("getMyMentions"); + GeneratedHttpRequest httpRequest = processor.createRequest(method); + + assertRequestLineEquals(httpRequest, "GET http://api.twitter.com/statuses/mentions.json HTTP/1.1"); + assertNonPayloadHeadersEqual(httpRequest, "Accept: application/json\n"); + assertPayloadEquals(httpRequest, null, null, false); + + // now make sure request filters apply by replaying + Iterables.getOnlyElement(httpRequest.getFilters()).filter(httpRequest); + Iterables.getOnlyElement(httpRequest.getFilters()).filter(httpRequest); + + assertRequestLineEquals(httpRequest, "GET http://api.twitter.com/statuses/mentions.json HTTP/1.1"); + // for example, using basic authentication, we should get "only one" + // header + assertNonPayloadHeadersEqual(httpRequest, "Accept: application/json\nAuthorization: Basic Zm9vOmJhcg==\n"); + assertPayloadEquals(httpRequest, null, null, false); + + assertResponseParserClassEquals(method, httpRequest, ParseJson.class); + assertSaxResponseParserClassEquals(method, null); + assertExceptionParserClassEquals(method, null); + + checkFilters(httpRequest); + + } + + @Override + protected void checkFilters(HttpRequest request) { + assertEquals(request.getFilters().size(), 1); + assertEquals(request.getFilters().get(0).getClass(), BasicAuthentication.class); + } + + @Override + protected TypeLiteral> createTypeLiteral() { + return new TypeLiteral>() { + }; + } + + @Override + protected Module createModule() { + return new TwitterRestClientModuleExtension(); + } + + @RequiresHttp + @ConfiguresRestClient + public static class TwitterRestClientModuleExtension extends TwitterRestClientModule { + + // Override here + } + + @Override + public RestContextSpec createContextSpec() { + // TODO take this out, when the service is registered in jclouds-core/rest.properties + Properties restProperties = new Properties(); + restProperties.setProperty("twitter.contextbuilder", "org.jclouds.twitter.TwitterContextBuilder"); + restProperties.setProperty("twitter.propertiesbuilder", "org.jclouds.twitter.TwitterPropertiesBuilder"); + + Properties props = new Properties(); + props.setProperty("twitter.endpoint", "http://api.twitter.com"); + return new RestContextFactory(restProperties).createContextSpec("twitter", "foo", "bar", props); + } +} diff --git a/sandbox/twitter/src/test/java/org/jclouds/twitter/TwitterClientLiveTest.java b/sandbox/twitter/src/test/java/org/jclouds/twitter/TwitterClientLiveTest.java new file mode 100644 index 0000000000..6b5ba5c8f5 --- /dev/null +++ b/sandbox/twitter/src/test/java/org/jclouds/twitter/TwitterClientLiveTest.java @@ -0,0 +1,107 @@ +/** + * + * Copyright (C) 2010 Cloud Conscious, LLC. + * + * ==================================================================== + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ==================================================================== + */ + +package org.jclouds.twitter; + +import static com.google.common.base.Preconditions.checkNotNull; +import static org.testng.Assert.assertTrue; + +import java.util.Properties; +import java.util.SortedSet; + +import org.jclouds.Constants; +import org.jclouds.logging.log4j.config.Log4JLoggingModule; +import org.jclouds.rest.RestContext; +import org.jclouds.rest.RestContextFactory; +import org.jclouds.twitter.domain.Status; +import org.testng.annotations.AfterGroups; +import org.testng.annotations.BeforeGroups; +import org.testng.annotations.Test; + +import com.google.common.collect.ImmutableSet; +import com.google.inject.Module; + +/** + * Tests behavior of {@code TwitterClient} + * + * @author Adrian Cole + */ +@Test(groups = "live", sequential = true) +public class TwitterClientLiveTest { + + protected TwitterClient client; + protected RestContext context; + + protected String provider = "twitter"; + protected String identity; + protected String credential; + protected String endpoint; + protected String apiversion; + + protected void setupCredentials() { + identity = checkNotNull(System.getProperty("test." + provider + ".identity"), "test." + provider + ".identity"); + credential = System.getProperty("test." + provider + ".credential"); + endpoint = System.getProperty("test." + provider + ".endpoint"); + apiversion = System.getProperty("test." + provider + ".apiversion"); + } + + protected Properties setupProperties() { + Properties overrides = new Properties(); + overrides.setProperty(Constants.PROPERTY_TRUST_ALL_CERTS, "true"); + overrides.setProperty(Constants.PROPERTY_RELAX_HOSTNAME, "true"); + overrides.setProperty(provider + ".identity", identity); + if (credential != null) + overrides.setProperty(provider + ".credential", credential); + if (endpoint != null) + overrides.setProperty(provider + ".endpoint", endpoint); + if (apiversion != null) + overrides.setProperty(provider + ".apiversion", apiversion); + return overrides; + } + + @BeforeGroups(groups = "live") + public void setupClient() { + setupCredentials(); + Properties overrides = setupProperties(); + + //TODO take this out, when the service is registered in jclouds-core/rest.properties + Properties restProperties = new Properties(); + restProperties.setProperty("twitter.contextbuilder", "org.jclouds.twitter.TwitterContextBuilder"); + restProperties.setProperty("twitter.propertiesbuilder", "org.jclouds.twitter.TwitterPropertiesBuilder"); + + context = new RestContextFactory(restProperties).createContext(provider, ImmutableSet. of(new Log4JLoggingModule()), + overrides); + + client = context.getApi(); + } + + @AfterGroups(groups = "live") + void tearDown() { + if (context != null) + context.close(); + } + + public void testGetMyMentions() throws Exception { + SortedSet response = client.getMyMentions(); + assert null != response; + long mentions = response.size(); + assertTrue(mentions >= 0); + } + +} diff --git a/sandbox/twitter/src/test/resources/log4j.xml b/sandbox/twitter/src/test/resources/log4j.xml new file mode 100755 index 0000000000..20fef23aed --- /dev/null +++ b/sandbox/twitter/src/test/resources/log4j.xml @@ -0,0 +1,110 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/sandbox/twitter/src/test/resources/test_mentions.json b/sandbox/twitter/src/test/resources/test_mentions.json new file mode 100644 index 0000000000..19e6deb04a --- /dev/null +++ b/sandbox/twitter/src/test/resources/test_mentions.json @@ -0,0 +1,77 @@ +[ { "created_at" : "Sat Oct 31 09:35:27 +0000 2009", + "favorited" : false, + "geo" : null, + "id" : 5310690603, + "in_reply_to_screen_name" : null, + "in_reply_to_status_id" : null, + "in_reply_to_user_id" : null, + "source" : "TweetDeck", + "text" : "RT @jclouds: live multi #cloud demo of jclouds connecting to 3 storage clouds from google appengine http://is.gd/4IXMh", + "truncated" : false, + "user" : { "created_at" : "Tue Apr 28 15:29:42 +0000 2009", + "description" : "Some random guy who seems to care about cloud collisions at siliconANGLE.com", + "favourites_count" : 245, + "followers_count" : 572, + "following" : false, + "friends_count" : 325, + "geo_enabled" : false, + "id" : 36093693, + "location" : "San Francisco ", + "name" : "James Watters", + "notifications" : false, + "profile_background_color" : "C6E2EE", + "profile_background_image_url" : "http://a1.twimg.com/profile_background_images/24067016/17361976.jpg", + "profile_background_tile" : true, + "profile_image_url" : "http://a3.twimg.com/profile_images/445071063/tiktaalik-transitional-fossil_normal.png", + "profile_link_color" : "1F98C7", + "profile_sidebar_border_color" : "C6E2EE", + "profile_sidebar_fill_color" : "DAECF4", + "profile_text_color" : "663B12", + "protected" : false, + "screen_name" : "wattersjames", + "statuses_count" : 1964, + "time_zone" : "Pacific Time (US & Canada)", + "url" : "http://siliconangle.net/ver2/author/jwatters/", + "utc_offset" : -28800, + "verified" : false + } + }, + { "created_at" : "Sat Oct 31 01:45:14 +0000 2009", + "favorited" : false, + "geo" : null, + "id" : 5303839785, + "in_reply_to_screen_name" : null, + "in_reply_to_status_id" : null, + "in_reply_to_user_id" : null, + "source" : "TweetDeck", + "text" : "RT @jclouds: come find out about #cloud storage and how to access it from #java in palo alto this Tuesday: http://is.gd/4IFA9", + "truncated" : false, + "user" : { "created_at" : "Sat Apr 26 06:13:08 +0000 2008", + "description" : "Jack of All Trades: Dad to anZel and Arden, VMware, vCloud, Security, Compliance, Former Developer", + "favourites_count" : 0, + "followers_count" : 474, + "following" : false, + "friends_count" : 199, + "geo_enabled" : false, + "id" : 14540593, + "location" : "Bay Area, CA", + "name" : "Jian Zhen", + "notifications" : false, + "profile_background_color" : "C6E2EE", + "profile_background_image_url" : "http://s.twimg.com/a/1256778767/images/themes/theme2/bg.gif", + "profile_background_tile" : false, + "profile_image_url" : "http://a3.twimg.com/profile_images/64445411/30b8b19_bigger_normal.jpg", + "profile_link_color" : "1F98C7", + "profile_sidebar_border_color" : "C6E2EE", + "profile_sidebar_fill_color" : "DAECF4", + "profile_text_color" : "663B12", + "protected" : false, + "screen_name" : "zhenjl", + "statuses_count" : 1981, + "time_zone" : "Pacific Time (US & Canada)", + "url" : "http://zhen.org", + "utc_offset" : -28800, + "verified" : false + } + } +] \ No newline at end of file