diff --git a/.gitignore b/.gitignore index c4496c4..0fb77b0 100644 --- a/.gitignore +++ b/.gitignore @@ -12,4 +12,3 @@ bin *.log *.jar -metrics/ diff --git a/pom.xml b/pom.xml index 4ef511c..aae78cf 100644 --- a/pom.xml +++ b/pom.xml @@ -92,7 +92,7 @@ org.slf4j slf4j-log4j12 - 1.6.6 + 1.7.6 org.apache.commons @@ -175,25 +175,25 @@ 4.11 - org.gitective - gitective-core - 0.9.9 - - - org.mongodb - mongo-java-driver - 2.11.3 + org.mongodb + mongo-java-driver + 2.11.3 - org.mongodb.morphia - morphia - 0.105 + org.mongodb.morphia + morphia + 0.105 - de.flapdoodle.embed - de.flapdoodle.embed.mongo - 1.42 - + org.eclipse.jdt + org.eclipse.jdt.core + 3.7.1 + + + de.flapdoodle.embed + de.flapdoodle.embed.mongo + 1.40 + @@ -247,6 +247,7 @@ org.apache.maven.plugins maven-source-plugin + 2.2.1 attach-sources @@ -260,6 +261,7 @@ org.apache.maven.plugins maven-javadoc-plugin + 2.9.1 attach-javadocs @@ -287,7 +289,7 @@ - + diff --git a/src/java/main/br/ufpe/cin/groundhog/database/GroundhogDB.java b/src/java/main/br/ufpe/cin/groundhog/database/GroundhogDB.java index dfb2270..18d54ac 100644 --- a/src/java/main/br/ufpe/cin/groundhog/database/GroundhogDB.java +++ b/src/java/main/br/ufpe/cin/groundhog/database/GroundhogDB.java @@ -4,6 +4,7 @@ import org.mongodb.morphia.Datastore; import org.mongodb.morphia.Morphia; +import org.mongodb.morphia.Key; import br.ufpe.cin.groundhog.GitHubEntity; @@ -17,14 +18,17 @@ * */ public class GroundhogDB { - private final String dbName; - private final MongoClient mongo; - private final Datastore datastore; + + private String dbName; + private MongoClient mongo; + private Datastore datastore; + private Morphia mapper; public GroundhogDB(String host, String dbName) throws UnknownHostException { this.dbName = dbName; this.mongo = new MongoClient(host); - this.datastore = new Morphia().createDatastore(this.mongo, dbName); + this.mapper = new Morphia(); + this.datastore = this.mapper.createDatastore(this.mongo, dbName); } public GroundhogDB(MongoClient mongo, String dbName) throws UnknownHostException { @@ -41,8 +45,8 @@ public static void query(GitHubEntity entity, String params) { * Receives a GitHub entity object and persists it to the database * @param entity, a {@link Object} representing one of the many GitHub entities covered by Groundhog */ - public void save(Object entity) { - this.datastore.save(entity); + public Key save(T entity) { + return this.datastore.save(entity); } public String getDbName() { @@ -56,4 +60,17 @@ public MongoClient getMongo() { public Datastore getDatastore() { return this.datastore; } -} + + public void setDatastore(Datastore datastore) { + this.datastore = datastore; + } + + public Morphia getMapper() { + return mapper; + } + + public void setMapper(Morphia mapper) { + this.mapper = mapper; + } + +} \ No newline at end of file diff --git a/src/java/main/br/ufpe/cin/groundhog/extractor/GitCommitExtractor.java b/src/java/main/br/ufpe/cin/groundhog/extractor/GitCommitExtractor.java index 3e051fb..7ea7b05 100644 --- a/src/java/main/br/ufpe/cin/groundhog/extractor/GitCommitExtractor.java +++ b/src/java/main/br/ufpe/cin/groundhog/extractor/GitCommitExtractor.java @@ -41,6 +41,21 @@ public List extractCommits(File project) { return null; } + public List getCommitList(File project) { + CommitListFilter list = new CommitListFilter(); + + String path = project.getAbsolutePath() + "/.git"; + CommitFinder finder = new CommitFinder(path); + + finder.setFilter(list).find(); +// +// for (RevCommit rev : list.getCommits()){ +// System.out.println(rev.getName() + " " + rev.getAuthorIdent().getName() + " " + rev.getShortMessage()); +// } +// + return list.getCommits(); + } + /** * A method that returns the number of commits that contain files with a given file extension * Example usage: diff --git a/src/java/main/br/ufpe/cin/groundhog/main/CmdMain.java b/src/java/main/br/ufpe/cin/groundhog/main/CmdMain.java index fe94563..d967b8e 100644 --- a/src/java/main/br/ufpe/cin/groundhog/main/CmdMain.java +++ b/src/java/main/br/ufpe/cin/groundhog/main/CmdMain.java @@ -3,6 +3,7 @@ import static java.lang.String.format; import java.io.File; +import java.net.UnknownHostException; import java.util.ArrayList; import java.util.Date; import java.util.HashMap; @@ -28,8 +29,14 @@ import br.ufpe.cin.groundhog.crawler.CrawlGoogleCode; import br.ufpe.cin.groundhog.crawler.CrawlSourceForge; import br.ufpe.cin.groundhog.crawler.ForgeCrawler; +import br.ufpe.cin.groundhog.database.GroundhogDB; import br.ufpe.cin.groundhog.http.HttpModule; import br.ufpe.cin.groundhog.http.Requests; +import br.ufpe.cin.groundhog.metrics.JavaProject; +import br.ufpe.cin.groundhog.metrics.exception.InvalidJavaFileException; +import br.ufpe.cin.groundhog.metrics.exception.InvalidJavaProjectPathException; +import br.ufpe.cin.groundhog.metrics.exception.InvalidSourceRootCodePathException; +import br.ufpe.cin.groundhog.metrics.exception.InvalidTestSourcePathException; import br.ufpe.cin.groundhog.parser.java.JavaParser; import br.ufpe.cin.groundhog.parser.java.MutableInt; import br.ufpe.cin.groundhog.parser.java.NotAJavaProjectException; @@ -171,7 +178,7 @@ public File downloadAndCheckoutProject(Project project, File repositoryFolder = repositoryFolderFuture.get(); logger.info(format("Project %s was downloaded", name)); - + logger.info(format("Project has %d forks", project.getForksCount())); logger.info(format("Checking out project %s to %s...", name, datetimeStr)); @@ -237,74 +244,99 @@ public void analyzeProject(Project project, File projectFolder, @Override public void run(JsonInputFile input) { try { - final File destinationFolder = input.getDest(); - final File metricsFolder = input.getOut(); - - logger.info("Creating temp folders..."); - createTempFolders(destinationFolder, metricsFolder); - - final Date datetime = input.getDatetime(); - final int nProjects = input.getNprojects(); - final String username = input.getSearch().getUsername(); - - // Search for projects - logger.info("Searching for projects... " + input.getSearch().getProjects()); - ForgeSearch search = defineForgeSearch(input.getForge()); - ForgeCrawler crawler = defineForgeCrawler(input.getForge(), destinationFolder); - - String term = input.getSearch().getProjects().get(0); - List allProjects = null; - if(username != null && !username.isEmpty()) { - allProjects = search.getProjects(term, username, 1); - } else { - allProjects = search.getProjects(term, 1,-1); - } - - //TODO the getProjects method already limits the number of searched projects - List projects = new ArrayList(); - for (int i = 0; i < nProjects; i++) { - if (i < allProjects.size()) { - projects.add(allProjects.get(i)); + //Java Metrics + if(input.getDBName()!= null || input.getJavaProjectSourceRootPath() != null || input.getJavaProjectSourceRootTestPath() != null){ + + final GroundhogDB ghdb = new GroundhogDB("127.0.0.1", input.getDBName()); + ghdb.getMapper().mapPackage("br.ufpe.cin.groundhog.metrics"); + + JavaProject project = new JavaProject(input.getJavaProjectPath()); + try { + project.generateStructure(input.getJavaProjectSourceRootPath(), input.getJavaProjectSourceRootTestPath()); + } catch (Exception e) { + logger.error("The struture of passed Java project can't be reconstructed!\nPlease check your parameters"); + e.printStackTrace(); + } + + project.generateMetrics( + input.getJavaProjectSourceRootTestPath() != null ? true: false, + ghdb); + + }else{ + + final File destinationFolder = input.getDest(); + final File metricsFolder = input.getOut(); + + logger.info("Creating temp folders..."); + createTempFolders(destinationFolder, metricsFolder); + + final Date datetime = input.getDatetime(); + final int nProjects = input.getNprojects(); + final String username = input.getSearch().getUsername(); + + // Search for projects + logger.info("Searching for projects... " + input.getSearch().getProjects()); + ForgeSearch search = defineForgeSearch(input.getForge()); + ForgeCrawler crawler = defineForgeCrawler(input.getForge(), destinationFolder); + + String term = input.getSearch().getProjects().get(0); + + List allProjects = null; + if(username != null && !username.isEmpty()) { + allProjects = search.getProjects(term, username, 1); + } else { + allProjects = search.getProjects(term, 1,-1); } - } - - // Download and analyze projects - logger.info("Downloading and processing projects..."); - ExecutorService ex = Executors.newFixedThreadPool(JsonInputFile.getMaxThreads()); - List> downloadFutures = crawler.asyncDownloadProjects(projects); - List> analysisFutures = new ArrayList>(); - - for (int i = 0; i < downloadFutures.size(); i++) { - final Project project = projects.get(i); - final Future repositoryFolderFuture = downloadFutures.get(i); - final Formater metricsFormat = input.getOutputformat(); - analysisFutures.add(ex.submit(new Runnable() { - @Override - public void run() { - File checkedOutRepository = downloadAndCheckoutProject(project, datetime, repositoryFolderFuture); + //TODO the getProjects method already limits the number of searched projects + List projects = new ArrayList(); + for (int i = 0; i < nProjects; i++) { + if (i < allProjects.size()) { + projects.add(allProjects.get(i)); + } + } - if (checkedOutRepository != null) { - analyzeProject(project, checkedOutRepository, datetime, metricsFolder, metricsFormat); + // Download and analyze projects + logger.info("Downloading and processing projects..."); + ExecutorService ex = Executors.newFixedThreadPool(JsonInputFile.getMaxThreads()); + List> downloadFutures = crawler.asyncDownloadProjects(projects); + List> analysisFutures = new ArrayList>(); + + for (int i = 0; i < downloadFutures.size(); i++) { + final Project project = projects.get(i); + final Future repositoryFolderFuture = downloadFutures.get(i); + final Formater metricsFormat = input.getOutputformat(); + + analysisFutures.add(ex.submit(new Runnable() { + @Override + public void run() { + File checkedOutRepository = downloadAndCheckoutProject(project, datetime, repositoryFolderFuture); + + if (checkedOutRepository != null) { + analyzeProject(project, checkedOutRepository, datetime, metricsFolder, metricsFormat); + } } - } - })); - } + })); + } - ex.shutdown(); - for (int i = 0; i < analysisFutures.size(); i++) { - try { - analysisFutures.get(i).get(); - } catch (InterruptedException | ExecutionException e) { - logger.error(format("Error while analyzing project %s", projects.get(i).getName()), e); + ex.shutdown(); + for (int i = 0; i < analysisFutures.size(); i++) { + try { + analysisFutures.get(i).get(); + } catch (InterruptedException | ExecutionException e) { + logger.error(format("Error while analyzing project %s", projects.get(i).getName()), e); + } } + logger.info("All projects were downloaded and analyzed!"); } - logger.info("All projects were downloaded and analyzed!"); - + } catch (GroundhogException e) { e.printStackTrace(); logger.error(e.getMessage()); + } catch (UnknownHostException e1) { + e1.printStackTrace(); + logger.error("Fail to acess MongoDB database, please check if its installed and running"); } } diff --git a/src/java/main/br/ufpe/cin/groundhog/main/CmdOptions.java b/src/java/main/br/ufpe/cin/groundhog/main/CmdOptions.java index 11c86e2..c55afad 100644 --- a/src/java/main/br/ufpe/cin/groundhog/main/CmdOptions.java +++ b/src/java/main/br/ufpe/cin/groundhog/main/CmdOptions.java @@ -51,6 +51,26 @@ public class CmdOptions { @Option(name = "-githubtoken", usage = "use authenticated requests to github api") private String gitHubOauthAcessToken; + @Option(name = "-jm", usage = "use to extract some metrics from java projects, like McGabe complexity and total lines of code (TLOC), to the project passed\n" + + "By default the path is your actual directory", + aliases = {"--generate-java-metrics"}, metaVar = "") + private File projectPath = new File(System.getProperty("user.dir")); + + @Option(name = "-src", usage = "use this option to provide the path of source root code directory from project root", + aliases = {"--source-root-code"}, metaVar = "") + private File child_path_src; + + @Option(name = "-srtc", usage = "use this option to provide the path of source root code directory from project root", + aliases = {"--source-root-test-code"}, metaVar = "") + private File child_path_srtc; + + @Option(name = "-dm", usage = "use this option to provide the name of Groundhog database when the generated metrics will be stored.\n" + + "By default the database name are java_metrics", + aliases = {"--database-name"}) + private String dbName = "java_metrics"; + + + private JsonInputFile input = null; @Argument @@ -172,7 +192,47 @@ public String getGitHubOauthAcessToken() { public void setGitHubOauthAcessToken(String gitHubOauthAcessToken) { this.gitHubOauthAcessToken = gitHubOauthAcessToken; } + + public File getProjectPath() { + return projectPath; + } + + public void setProjectPath(File projectPath) { + this.projectPath = projectPath; + } + + public File getChild_path_src() { + return child_path_src; + } + + public void setChild_path_src(File child_path_src) { + this.child_path_src = child_path_src; + } + public File getChild_path_srtc() { + return child_path_srtc; + } + + public void setChild_path_srtc(File child_path_srtc) { + this.child_path_srtc = child_path_srtc; + } + + public String getDbName() { + return dbName; + } + + public void setDbName(String dbName) { + this.dbName = dbName; + } + + public JsonInputFile getInput() { + return input; + } + + public void setInput(JsonInputFile input) { + this.input = input; + } + @Option(name = "-in", usage = "all inputs together in one json file") public void setInputFile(File inputFile) { try { diff --git a/src/java/main/br/ufpe/cin/groundhog/main/JsonInputFile.java b/src/java/main/br/ufpe/cin/groundhog/main/JsonInputFile.java index 3c60238..9a6a1e5 100644 --- a/src/java/main/br/ufpe/cin/groundhog/main/JsonInputFile.java +++ b/src/java/main/br/ufpe/cin/groundhog/main/JsonInputFile.java @@ -27,6 +27,10 @@ public final class JsonInputFile { private String outputformat; private Search search; private String gitHubOauthAcessToken; + private File javaprojectpath; + private File child_path_src; + private File child_path_srtc; + private String dbname; public JsonInputFile(CmdOptions opt) { super(); @@ -38,6 +42,10 @@ public JsonInputFile(CmdOptions opt) { this.outputformat = opt.getMetricsFormat(); this.search = new Search(opt.getArguments(), opt.getUsername()); this.gitHubOauthAcessToken = opt.getGitHubOauthAcessToken(); + this.javaprojectpath = opt.getProjectPath(); + this.child_path_src = opt.getChild_path_src(); + this.child_path_srtc = opt.getChild_path_srtc(); + this.dbname = opt.getDbName(); } //TODO: this should be discovered dynamically @@ -87,6 +95,36 @@ public Search getSearch() { return this.search; } + public File getJavaProjectPath(){ + return this.javaprojectpath; + } + + public File getJavaProjectSourceRootPath(){ + if(this.child_path_src == null){ + return null; + }else if(this.child_path_src.isDirectory()){ + return this.child_path_src; + }else{ + File to_return = new File(javaprojectpath, this.child_path_src.toString()); + return to_return; + } + } + + public File getJavaProjectSourceRootTestPath(){ + if(this.child_path_srtc == null){ + return null; + }else if(this.child_path_srtc.isDirectory()){ + return this.child_path_srtc; + }else{ + File to_return = new File(javaprojectpath, this.child_path_srtc.toString()); + return to_return; + } + } + + public String getDBName(){ + return this.dbname; + } + public String toString() { return Objects.toStringHelper("") .add("forge", forge) @@ -96,6 +134,10 @@ public String toString() { .add("nproject", nprojects) .add("outputformat", outputformat) .add("search", search) + .add("javaprojectpath", javaprojectpath) + .add("javaprojectsourcerootpath", child_path_src) + .add("javaprojectsourcetestrootpath", child_path_srtc) + .add("dbname", dbname) .toString(); } } diff --git a/src/java/main/br/ufpe/cin/groundhog/metrics/GroundhogASTVisitor.java b/src/java/main/br/ufpe/cin/groundhog/metrics/GroundhogASTVisitor.java new file mode 100644 index 0000000..3e3d89d --- /dev/null +++ b/src/java/main/br/ufpe/cin/groundhog/metrics/GroundhogASTVisitor.java @@ -0,0 +1,251 @@ +package br.ufpe.cin.groundhog.metrics; + +import java.util.Stack; + +import org.eclipse.jdt.core.Flags; +import org.eclipse.jdt.core.dom.*; + +class GroundhogASTVisitor extends ASTVisitor{ + + Statistics stat; + + /** + * Auxiliar fields to extract metrics + */ + int methods = 0; + int fields = 0; + int methodCalls = 0; + int staticMethod = 0; + int staticField = 0; + int cycloComplexity = 1; + int returns = 0; + + //fields used to nested block depth metric calculation + Stack depth = new Stack(); + Stack maxDepth = new Stack(); + + /** + * Flag for preventing the calculation of methods from interfaces + */ + boolean countMethods = true; + + public boolean visit(AnonymousClassDeclaration node){ + this.stat.anonymousClasses++; + return true; + } + + public boolean visit(TypeDeclaration td){ + if (td.isInterface()) { + this.countMethods = false; + this.stat.interfaces++; + } else { + this.countMethods = true; + this.stat.classes++; + } + + this.fields = 0; + this.methods = 0; + this.staticMethod = 0; + this.staticField = 0; + + return true; + } + + public void endVisit(TypeDeclaration td){ + + Util.safeAddToHashTable(this.stat.fieldCounter, this.fields); + Util.safeAddToHashTable(this.stat.methodCounter,this.methods); + Util.safeAddToHashTable(this.stat.sMethodCounter,this.staticMethod); + Util.safeAddToHashTable(this.stat.sFieldCounter,this.staticField); + } + + public boolean visit(MethodDeclaration md){ + + //We only take the metrics if the method isn't from an interface + if (this.countMethods) { + + this.methods++; + this.methodCalls = 0; + this.cycloComplexity = 1; + this.returns = 0; + + //nested block depth calculation + this.depth.push(0); + this.maxDepth.push(0); + + String[] lines = md.toString().split("\n"); + Util.safeAddToHashTable(this.stat.lineCounter,lines.length); + int f = md.getModifiers(); + if(Flags.isStatic(f)) this.staticMethod++; + int param = md.parameters().size(); + Util.safeAddToHashTable(this.stat.parameters,param); + } + return true; + } + + public void endVisit(MethodDeclaration md){ + + //The same as the visit, we only take metrics if the method isn't from an interface + if (this.countMethods){ + + this.depth.pop(); + int max = this.maxDepth.pop(); + Util.safeAddStackTop(this.depth, max); + this.cycloComplexity += 2*Math.max(0, this.returns-1); + Util.safeAddToHashTable(this.stat.cycloCounter,this.cycloComplexity); + Util.safeAddToHashTable(this.stat.depCounter,max); + Util.safeAddToHashTable(this.stat.methodCall,this.methodCalls); + } + } + + public boolean visit(MethodInvocation mi){ + this.methodCalls++; + return true; + } + + public boolean visit(ForStatement fs){ + this.cycloComplexity++; + this.inspecionarExpressao(fs.getExpression()); + return true; + } + + public boolean visit(WhileStatement ws){ + this.cycloComplexity++; + this.inspecionarExpressao(ws.getExpression()); + return true; + } + + public boolean visit(IfStatement is){ + this.cycloComplexity++; + this.inspecionarExpressao(is.getExpression()); + return true; + } + + public boolean visit(BreakStatement bs){ + this.cycloComplexity++; + return true; + } + + public boolean visit(ContinueStatement cs){ + this.cycloComplexity++; + return true; + } + + public boolean visit(ExpressionStatement es){ + this.inspecionarExpressao(es.getExpression()); + return true; + } + + public boolean visit(ConditionalExpression ce) { + cycloComplexity++; + inspecionarExpressao(ce.getExpression()); + return true; + } + + public boolean visit(DoStatement ds){ + this.cycloComplexity++; + this.inspecionarExpressao(ds.getExpression()); + return true; + } + + public boolean visit(TryStatement ts){ + if(ts.getFinally()!=null){ + this.cycloComplexity++; + } + return true; + } + + public boolean visit(CatchClause cc){ + this.cycloComplexity++; + return true; + } + + public boolean visit(ThrowStatement ts){ + this.cycloComplexity++; + return true; + } + + public boolean visit(SwitchCase sc){ + this.cycloComplexity++; + return true; + } + + public boolean visit(ReturnStatement rs){ + this.returns++; + return true; + } + + public boolean visit(FieldDeclaration fd){ + + this.fields++; + if(Flags.isStatic(fd.getModifiers())){ + this.staticField++; + } + + return true; + } + + public boolean visit(Block node){ + + //Using an stack strategy to count the max nested block depth + //If I visit an block, so I have one more level of code + if(!this.depth.empty()){ + /** + * We also want to calculate block nested depth for methods + * so, the stack will have at least one element if we was visited + * an method before + */ + Util.safeAddStackTop(this.depth, 1); + } + + return true; + + } + + public void endVisit(Block node) { + /** + * Using an stack strategy to count the max nested block depth + * If I end the visit of a block, so is time to check how deep the code are. + * If the actual nested level is more than actual maximum, so set maximum to + * this new maximum. + */ + if(!this.depth.empty()){ + /** + * We also want to calculate block nested depth for methods + * so, the stack will have at least one element if we was visited + * an method before + * + * Once I finish to visit a block, I need to reduce the nested level because + * we complete one sub-level of nested block + */ + int temp = Util.safeAddStackTop(depth, -1); + if(temp > this.maxDepth.peek()){ + this.maxDepth.pop(); + this.maxDepth.push(temp); + } + } + } + + public void inspecionarExpressao(Expression e) { + if (e != null) { + String expression = e.toString(); + char[] chars = expression.toCharArray(); + for (int i = 0; i < chars.length-1; i++) { + char next = chars[i]; + if ((next == '&' || next == '|')&&(next == chars[i+1])) { + this.cycloComplexity++; + } + } + } + } + + public void setStatistics(Statistics stat){ + this.stat = stat; + } + + public Statistics getStatistics(){ + Statistics to_return = this.stat; + this.stat = null; + return to_return; + } +} \ No newline at end of file diff --git a/src/java/main/br/ufpe/cin/groundhog/metrics/JavaFile.java b/src/java/main/br/ufpe/cin/groundhog/metrics/JavaFile.java new file mode 100644 index 0000000..b27fe9d --- /dev/null +++ b/src/java/main/br/ufpe/cin/groundhog/metrics/JavaFile.java @@ -0,0 +1,173 @@ +package br.ufpe.cin.groundhog.metrics; + +import java.io.File; +import java.io.FileNotFoundException; +import java.util.Scanner; + +import org.bson.types.ObjectId; +import org.eclipse.jdt.core.dom.AST; +import org.eclipse.jdt.core.dom.ASTParser; +import org.eclipse.jdt.core.dom.CompilationUnit; + +import br.ufpe.cin.groundhog.database.GroundhogDB; +import br.ufpe.cin.groundhog.metrics.exception.InvalidJavaFileException; + +import com.google.gson.annotations.SerializedName; +import org.mongodb.morphia.annotations.Entity; +import org.mongodb.morphia.annotations.Id; +import org.mongodb.morphia.annotations.Indexed; +import org.mongodb.morphia.annotations.Reference; +import org.mongodb.morphia.annotations.Transient; + +/** + * Represents a java class in Groundhog metrics extractor + * @author Bruno Soares, Tulio Lajes, Valdemir Andrade + * @since 0.1.0 + */ + +@Entity("javafiles") +public class JavaFile { + + /** + * Transient annotations will not be stored in the database + */ + + @Id + @Indexed(unique=true, dropDups=true) + ObjectId id; + + @Transient + private File path; + + @SerializedName("absolutepath") + private String absolutePath; + + @SerializedName("name") + private String name; + + @Transient + private ASTParser parser; + + @Transient + private Scanner scanner; + + @Transient + private CompilationUnit cu; + + @Transient + private Statistics stat; + + @Reference + @SerializedName("sttablefile") + private StatisticsTableFile table; + + public Statistics getStat() { + return stat; + } + + /** + * Default constructor used by morphia to create a empty object setting the annotated attributes using reflection + */ + public JavaFile(){} + + public JavaFile(File path, String name) throws InvalidJavaFileException{ + + this.path = path; + this.name = name; + commonInit(); + } + + public JavaFile(File path) throws InvalidJavaFileException{ + + this.path = path; + this.name = path.getName(); + commonInit(); + } + + public JavaFile(String absolutePath, String name) throws InvalidJavaFileException{ + + this.path = new File(absolutePath); + this.name = name; + commonInit(); + + } + + public JavaFile(String path) throws InvalidJavaFileException{ + + this.path = new File(path); + this.name = this.path.isFile() ? this.path.getName() : ""; + commonInit(); + } + + private void commonInit() throws InvalidJavaFileException{ + + this.absolutePath = this.path.getAbsolutePath(); + this.table = new StatisticsTableFile(); + + //Generate statistics structure + this.stat = new Statistics(); + this.stat.compilationUnits++; + + try{ + + //Read java file + this.scanner = new Scanner(this.path); + this.scanner.useDelimiter("\\Z"); + + //Generate AST + this.parser = ASTParser.newParser(AST.JLS3); + String source = this.scanner.next(); + this.parser.setSource(source.toCharArray()); + + //Close scanner + this.scanner.close(); + + //Generate compilation unit to be visited + this.cu = (CompilationUnit) parser.createAST(null); + this.stat.totalCode = Util.countCodeLines(source); + }catch(FileNotFoundException e){ + + throw new InvalidJavaFileException(); + } + } + + @Override + public String toString(){ + + return "File: " + this.name; + } + + public File getFile(){ + + return path; + } + + public void setFile(File file){ + + this.path = file; + } + + public StatisticsTableFile getTable() { + return table; + } + + public void setTable(StatisticsTableFile table) { + this.table = table; + } + + public Statistics generateMetrics(GroundhogASTVisitor visitor, MetricsCollector collector){ + + visitor.setStatistics(this.stat); + this.cu.accept(visitor); + this.stat = visitor.getStatistics(); + collector.processFileLevel(this.table, this.stat); + return this.stat; + } + + public Statistics generateMetrics(GroundhogASTVisitor visitor, MetricsCollector collector, GroundhogDB db){ + Statistics to_return = generateMetrics(visitor, collector); + db.save(this.table); + db.save(this); + return to_return; + } +} diff --git a/src/java/main/br/ufpe/cin/groundhog/metrics/JavaPackage.java b/src/java/main/br/ufpe/cin/groundhog/metrics/JavaPackage.java new file mode 100644 index 0000000..c0832ee --- /dev/null +++ b/src/java/main/br/ufpe/cin/groundhog/metrics/JavaPackage.java @@ -0,0 +1,196 @@ +package br.ufpe.cin.groundhog.metrics; + +import java.io.File; +import java.util.ArrayList; +import java.util.List; + +import org.bson.types.ObjectId; +import org.mongodb.morphia.annotations.Entity; +import org.mongodb.morphia.annotations.Id; +import org.mongodb.morphia.annotations.Indexed; +import org.mongodb.morphia.annotations.Reference; +import org.mongodb.morphia.annotations.Transient; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.google.gson.annotations.SerializedName; + +import br.ufpe.cin.groundhog.database.GroundhogDB; +import br.ufpe.cin.groundhog.metrics.exception.InvalidJavaFileException; + +/** + * Represents a java package in Groundhog metrics extractor + * @author Bruno Soares, Tulio Lajes, Valdemir Andrade + * @since 0.1.0 + */ + +@Entity("javapackages") +public class JavaPackage { + + @Transient + private static Logger logger = LoggerFactory.getLogger(JavaProject.class); + + @Id + @Indexed(unique=true, dropDups=true) + ObjectId id; + + @Reference + @SerializedName("javafiles") + private ArrayList files; + + @Transient + private File path; + + @SerializedName("absolutepath") + private String absolutePath; + + @SerializedName("name") + private String name; + + @Transient + private Statistics statistics = new Statistics(); + + public ObjectId getId() { + return id; + } + + public void setId(ObjectId id) { + this.id = id; + } + + public ArrayList getFiles() { + return files; + } + + public void setFiles(ArrayList files) { + this.files = files; + } + + public File getPath() { + return path; + } + + public void setPath(File path) { + this.path = path; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public Statistics getStatistics() { + return statistics; + } + + public void setStatistics(Statistics statistics) { + this.statistics = statistics; + } + + public StatisticsTablePackage getTable() { + return table; + } + + public void setTable(StatisticsTablePackage table) { + this.table = table; + } + + @Reference + @SerializedName("sttablepackage") + private StatisticsTablePackage table; + + /** + * Default constructor used by morphia to create a empty object setting the annotated attributes using reflection + */ + public JavaPackage(){} + + public JavaPackage(File path, String name) throws InvalidJavaFileException{ + this.path = path; + this.name = name; + commonInit(); + } + + public JavaPackage(File path) throws InvalidJavaFileException{ + this.path = path; + this.name = path.getName(); + commonInit(); + } + + public JavaPackage(String absolutePath, String name) throws InvalidJavaFileException{ + this.path = new File(absolutePath); + this.name = name; + commonInit(); + } + + public JavaPackage(String path) throws InvalidJavaFileException{ + this.path = new File(path); + this.name = this.path.isDirectory() ? this.path.getName() : ""; + commonInit(); + } + + public void commonInit() throws InvalidJavaFileException{ + this.files = new ArrayList(); + this.table = new StatisticsTablePackage(); + detectJavaFiles(); + } + + @Override + public String toString() { + return "Package: " + this.name; + } + + public List generateMetrics(GroundhogASTVisitor visitor, MetricsCollector collector){ + + List stats = new ArrayList(); + + //Collect metrics + for(JavaFile file : this.files){ + stats.add(file.generateMetrics(visitor, collector)); + } + + collector.processPackageLevel(table, stats); + logger.debug(table.toString()); + return stats; + } + + public List generateMetrics(GroundhogASTVisitor visitor, MetricsCollector collector, GroundhogDB db){ + List stats = new ArrayList(); + + //Collect metrics + for(JavaFile file : this.files){ + stats.add(file.generateMetrics(visitor, collector,db)); + } + + collector.processPackageLevel(table, stats); + + logger.debug(table.toString()); + + db.save(this.table); + db.save(this); + + return stats; + } + + private void detectJavaFiles() throws InvalidJavaFileException{ + + this.absolutePath = this.path.getAbsolutePath(); + for (File file : this.path.listFiles()){ + if(file.getName().endsWith(".java")){ + this.files.add(new JavaFile(file,file.getName())); + logger.debug("Java File " + file.getName() + " detected!"); + } + } + } + + public String getAbsolutePath() { + return absolutePath; + } + + public void setAbsolutePath(String absolutePath) { + this.absolutePath = absolutePath; + } + +} diff --git a/src/java/main/br/ufpe/cin/groundhog/metrics/JavaProject.java b/src/java/main/br/ufpe/cin/groundhog/metrics/JavaProject.java new file mode 100644 index 0000000..9218040 --- /dev/null +++ b/src/java/main/br/ufpe/cin/groundhog/metrics/JavaProject.java @@ -0,0 +1,417 @@ +package br.ufpe.cin.groundhog.metrics; + +import java.io.File; +import java.util.ArrayList; +import java.util.regex.Matcher; + +import org.bson.types.ObjectId; +import org.mongodb.morphia.annotations.Entity; +import org.mongodb.morphia.annotations.Id; +import org.mongodb.morphia.annotations.Indexed; +import org.mongodb.morphia.annotations.Reference; +import org.mongodb.morphia.annotations.Transient; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.google.gson.annotations.SerializedName; + +import br.ufpe.cin.groundhog.database.GroundhogDB; +import br.ufpe.cin.groundhog.metrics.exception.InvalidJavaFileException; +import br.ufpe.cin.groundhog.metrics.exception.InvalidJavaProjectPathException; +import br.ufpe.cin.groundhog.metrics.exception.InvalidSourceRootCodePathException; +import br.ufpe.cin.groundhog.metrics.exception.InvalidTestSourcePathException; + +/** + * Represents a java project in Groundhog metrics extractor + * @author Bruno Soares, Tulio Lajes, Valdemir Andrade + * @since 0.1.0 + */ + +@Entity("javaprojects") +public class JavaProject { + + @Transient + private static Logger logger = LoggerFactory.getLogger(JavaProject.class); + + @Id + @Indexed(unique=true, dropDups=true) + private ObjectId id; + + public static final String default_source_root_code = "src"; + + @Reference + private ArrayList code_packages; + + @Reference + private ArrayList test_packages; + + @Transient + private File path; + + @Transient + private File src; + + @Transient + private File srtc; + + @SerializedName("absolutepath") + private String absolutePath; + + public ObjectId getId() { + return id; + } + + public void setId(ObjectId id) { + this.id = id; + } + + public ArrayList getCode_packages() { + return code_packages; + } + + public void setCode_packages(ArrayList code_packages) { + this.code_packages = code_packages; + } + + public ArrayList getTest_packages() { + return test_packages; + } + + public void setTest_packages(ArrayList test_packages) { + this.test_packages = test_packages; + } + + public File getPath() { + return path; + } + + public void setPath(File path) { + this.path = path; + } + + public File getSrc() { + return src; + } + + public void setSrc(File src) { + this.src = src; + } + + public File getSrtc() { + return srtc; + } + + public void setSrtc(File srtc) { + this.srtc = srtc; + } + + public String getAbsolutePath() { + return absolutePath; + } + + public void setAbsolutePath(String absolutePath) { + this.absolutePath = absolutePath; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public GroundhogASTVisitor getVisitor() { + return visitor; + } + + public void setVisitor(GroundhogASTVisitor visitor) { + this.visitor = visitor; + } + + public StatisticsTable getSt_code() { + return st_code; + } + + public void setSt_code(StatisticsTable st_code) { + this.st_code = st_code; + } + + public StatisticsTable getSt_test() { + return st_test; + } + + public void setSt_test(StatisticsTable st_test) { + this.st_test = st_test; + } + + public Statistics getStatistics() { + return statistics; + } + + public void setStatistics(Statistics statistics) { + this.statistics = statistics; + } + + public MetricsCollector getCollector() { + return collector; + } + + public void setCollector(MetricsCollector collector) { + this.collector = collector; + } + + public static String getDefaultSourceRootCode() { + return default_source_root_code; + } + + @SerializedName("name") + private String name; + + @Transient + private GroundhogASTVisitor visitor; + + @Transient + private StatisticsTable st_code; + + @Transient + private StatisticsTable st_test; + + @Transient + private Statistics statistics = new Statistics(); + + @Transient + private MetricsCollector collector; + + /** + * Default constructor used by morphia to create a empty object setting the annotated attributes using reflection + */ + public JavaProject() {} + + public JavaProject(File path, String name) throws InvalidJavaProjectPathException { + + this.path = path; + this.name = name; + commonInit(); + } + + public JavaProject(File path) throws InvalidJavaProjectPathException{ + + this.path = path; + this.name = path.getName(); + commonInit(); + } + + public JavaProject(String absolutePath, String name) throws InvalidJavaProjectPathException{ + + this.path = new File(absolutePath); + this.name = name; + commonInit(); + } + + public JavaProject(String path) throws InvalidJavaProjectPathException{ + + this.path = new File(path); + this.name = this.path.isDirectory() ? this.path.getName() : ""; + commonInit(); + } + + private void commonInit() throws InvalidJavaProjectPathException{ + + checkPath(); + this.absolutePath = this.path.getAbsolutePath(); + this.collector = new MetricsCollector(); + this.code_packages = new ArrayList(); + this.test_packages = new ArrayList(); + this.visitor = new GroundhogASTVisitor(); + } + + private void checkPath() throws InvalidJavaProjectPathException{ + + if(!this.path.isDirectory()){ + + logger.error("This project has an invalid path!"); + + throw new InvalidJavaProjectPathException(); + } + } + + public boolean generateStructure(String src, String srtc) throws InvalidJavaProjectPathException, InvalidSourceRootCodePathException, InvalidTestSourcePathException, InvalidJavaFileException{ + + if(this.path == null || !this.path.isDirectory()) + return false; + else{ + detectSourceRootCode(src); + detectSourceRootTestCode(srtc); + detectCodePackages(); + detectTestCodePackages(); + return true; + } + } + + public boolean generateStructure(File src, File srtc) throws InvalidJavaProjectPathException, InvalidSourceRootCodePathException, InvalidTestSourcePathException, InvalidJavaFileException{ + + if(this.path == null || !this.path.isDirectory()) + return false; + else{ + + detectSourceRootCode(src); + detectCodePackages(); + + if(srtc != null){ + detectSourceRootTestCode(srtc); + detectTestCodePackages(); + } + + return true; + } + } + + private void detectSourceRootCode(String source_root_code) throws InvalidJavaProjectPathException, InvalidSourceRootCodePathException{ + logger.info("Detecting sorce root code..."); + //This line has been commented because we need to decide how to detect the correct java source root code + //String scr = (source_root_code == null ? JavaProject.default_source_root_code : source_root_code); + + File temp_src = null; + String src = source_root_code; + + temp_src = new File(this.path.getAbsolutePath(), src); + + detectSourceRootCode(temp_src); + + } + + private void detectSourceRootCode(File source_root_code) throws InvalidJavaProjectPathException, InvalidSourceRootCodePathException{ + + try{ + if(source_root_code.exists()) + this.src = source_root_code; + else + throw new InvalidSourceRootCodePathException(); + }catch (NullPointerException e){ + System.err.println("Source root code not found!"); + } + } + + private void detectSourceRootTestCode(String source_test_root_code) throws InvalidTestSourcePathException{ + logger.info("Detecting sorce root test code..."); + + File temp_srtc = null; + + temp_srtc = new File(this.path.getAbsolutePath(),source_test_root_code); + + detectSourceRootTestCode(temp_srtc); + } + + private void detectSourceRootTestCode(File source_test_root_code) throws InvalidTestSourcePathException{ + + try{ + if(source_test_root_code.exists()) + this.srtc = source_test_root_code; + else + throw new InvalidTestSourcePathException(); + }catch (NullPointerException e){ + System.err.println("Source root test code not found!"); + } + } + + @Override + public String toString() { + return "Name: " + this.name + "\n" + + "SRC: " + ((this.src == null) ? "not found\n" : (this.src.getAbsolutePath() + "\n")) + + "SRTC: " + ((this.srtc == null) ? "not found" : this.srtc.getAbsolutePath()); + } + + private void detectPackages(File dir,ArrayList packages, File src) throws InvalidJavaFileException{ + + //Check if this project have files on default package + if(dir.equals(this.src) && hasJavaFiles(dir)){ + logger.debug("Package default detected!"); + packages.add(new JavaPackage(dir,"default")); + } + + for(File file : dir.listFiles()){ + //We have a directory and java files, so we have a package + if(file.isDirectory() && hasJavaFiles(file)){ + logger.debug("Package " + extractPackageName(src,file) + " detected!"); + JavaPackage java_package = new JavaPackage(file,extractPackageName(src,file)); + packages.add(java_package); + detectPackages(file,packages,src); + }else if(file.isDirectory()){ + //Search for packages inside actual package + detectPackages(file,packages,src); + } + } + + } + + private void detectCodePackages() throws InvalidJavaFileException{ + if(this.src != null){ + detectPackages(this.src, this.code_packages, this.src); + } + } + + private void detectTestCodePackages() throws InvalidJavaFileException{ + if(this.srtc != null){ + detectPackages(this.srtc, this.test_packages, this.srtc); + } + } + + private boolean hasJavaFiles(File dir){ + + for (File file : dir.listFiles()){ + if(file.getName().endsWith(".java")) return true; + } + + return false; + } + + private String extractPackageName(File src, File dir){ + return dir.getAbsolutePath(). + replace(src.getAbsolutePath()+File.separator, "") + .replaceAll(Matcher.quoteReplacement(File.separator), "."); + } + + public boolean generateMetrics(boolean include_tests){ + + //For each code package of this project generate their metrics + for (JavaPackage _package : this.code_packages){ + _package.generateMetrics(this.visitor, this.collector); + } + + logger.info("All code packages done!"); + + if(include_tests){ + for (JavaPackage _package : this.test_packages){ + _package.generateMetrics(this.visitor,this.collector); + } + } + + logger.info("All test packages done!"); + + return true; + } + + public boolean generateMetrics(boolean include_tests, GroundhogDB db){ + + //For each code package of this project generate their metrics + for (JavaPackage _package : this.code_packages){ + _package.generateMetrics(this.visitor, this.collector,db); + } + + logger.info("All code packages done!"); + + if(include_tests){ + + for (JavaPackage _package : this.test_packages){ + _package.generateMetrics(this.visitor,this.collector,db); + } + + logger.info("All test packages done!"); + } + + db.save(this); + + return true; + } +} diff --git a/src/java/main/br/ufpe/cin/groundhog/metrics/MetricsCollector.java b/src/java/main/br/ufpe/cin/groundhog/metrics/MetricsCollector.java new file mode 100644 index 0000000..e8f11d1 --- /dev/null +++ b/src/java/main/br/ufpe/cin/groundhog/metrics/MetricsCollector.java @@ -0,0 +1,135 @@ +package br.ufpe.cin.groundhog.metrics; + +import java.util.Hashtable; +import java.util.List; +import java.util.Map; + +public final class MetricsCollector { + + private long max; + private double avg; + private long total; + + + private void process(Hashtable table, long fileCount){ + long denominator = 0; + long numerator = 0; + + for (Map.Entry map : table.entrySet()){ + denominator += map.getValue(); + numerator += (map.getKey() * map.getValue()); + if(this.max < map.getKey()) this.max = map.getKey(); + } + + //This code activates the calculation of the avg of the pakages taking into account its files rather than its methods. + //if(fileCount > 1) this.avg = Util.safeCalculateAvg(numerator, fileCount); + //else this.avg = Util.safeCalculateAvg(numerator, denominator); + + this.avg = Util.safeCalculateAvg(numerator, denominator); + + this.total = numerator; + } + + private void clear(){ + this.max = 0; + this.avg = 0.0; + this.total = 0; + } + + private void commonProcess(StatisticsTable table, Statistics stat){ + clear(); + process(stat.methodCall,stat.fileCount); + table.FOUT_avg = this.avg; + table.FOUT_max = this.max; + table.FOUT_sum = this.total; + + clear(); + process(stat.lineCounter,stat.fileCount); + table.MLOC_avg = this.avg; + table.MLOC_max = this.max; + table.MLOC_sum = this.total; + + clear(); + process(stat.depCounter,stat.fileCount); + table.NBD_avg = this.avg; + table.NBD_max = this.max; + table.NBD_sum = this.total; + + clear(); + process(stat.fieldCounter,stat.fileCount); + table.NOF_avg = this.avg; + table.NOF_max = this.max; + table.NOF_sum = this.total; + + clear(); + process(stat.sFieldCounter,stat.fileCount); + table.NSF_avg = this.avg; + table.NSF_max = this.max; + table.NSF_sum = this.total; + + clear(); + process(stat.methodCounter,stat.fileCount); + table.NOM_avg = this.avg; + table.NOM_max = this.max; + table.NOM_sum = this.total; + + clear(); + process(stat.sMethodCounter,stat.fileCount); + table.NSM_avg = this.avg; + table.NSM_max = this.max; + table.NSM_sum = this.total; + + clear(); + process(stat.parameters,stat.fileCount); + table.PAR_avg = this.avg; + table.PAR_max = this.max; + table.PAR_sum = this.total; + + clear(); + process(stat.cycloCounter,stat.fileCount); + table.VG_avg = this.avg; + table.VG_max = this.max; + table.VG_sum = this.total; + } + + public void processFileLevel(StatisticsTableFile table, Statistics stat){ + + commonProcess(table, stat); + table.ACD = stat.anonymousClasses; + table.NOI = stat.interfaces; + table.NOT = stat.classes; + table.TLOC = stat.totalCode; + } + + public void processPackageLevel(StatisticsTablePackage table, List stats){ + + //Join all statistics to obtain package level metrics + Statistics temp = new Statistics(true); + for (Statistics st : stats) { + temp.merge(st); + } + + commonProcess(table, temp); + + table.ACD_sum = temp.anonymousClasses; + table.ACD_max = temp.anonymousClasses_max; + table.ACD_avg = Util.safeCalculateAvg(temp.anonymousClasses, temp.fileCount); + + table.NOI_sum = temp.interfaces; + table.NOI_max = temp.interfaces_max; + table.NOI_avg = Util.safeCalculateAvg(temp.interfaces, temp.fileCount); + + table.NOT_sum = temp.classes; + table.NOT_max = temp.classes_max; + table.NOT_avg = Util.safeCalculateAvg(temp.classes, temp.fileCount); + + table.TLOC_sum = temp.totalCode; + table.TLOC_max = temp.totalCode_max; + table.TLOC_avg = Util.safeCalculateAvg(temp.totalCode, temp.fileCount); + + table.NOCU = temp.compilationUnits; + + } + +} + diff --git a/src/java/main/br/ufpe/cin/groundhog/metrics/Statistics.java b/src/java/main/br/ufpe/cin/groundhog/metrics/Statistics.java new file mode 100644 index 0000000..f269b64 --- /dev/null +++ b/src/java/main/br/ufpe/cin/groundhog/metrics/Statistics.java @@ -0,0 +1,117 @@ +package br.ufpe.cin.groundhog.metrics; + +import java.util.Hashtable; + +public class Statistics { + /*It's necessary to use final variables in order to interact with + * the code inside ASTVisitor class + */ + + /** + * Accumulators for method metrics + */ + public Hashtable methodCall = new Hashtable(); + public Hashtable lineCounter = new Hashtable(); + public Hashtable depCounter = new Hashtable(); + public Hashtable parameters = new Hashtable(); + public Hashtable cycloCounter = new Hashtable(); + + /** + * Accumulators for classes metrics + */ + public Hashtable fieldCounter = new Hashtable(); + public Hashtable methodCounter = new Hashtable(); + public Hashtable sFieldCounter = new Hashtable(); + public Hashtable sMethodCounter = new Hashtable(); + + /** + * Accumulators for files metrics + */ + public long anonymousClasses = 0; + public long anonymousClasses_max = 0; + public long interfaces = 0; + public long interfaces_max = 0; + public long classes = 0; + public long classes_max = 0; + public long totalCode = 0; + public long totalCode_max = 0; + + /** + * Accumulators for package metrics + */ + public long compilationUnits = 0; + + /** + * Count of how many statistics this statistics represents + */ + public long fileCount = 1; + + public Statistics() {} + + public Statistics(boolean Package){ + this.fileCount = 0; + } + + public void merge(Statistics statistics){ + this.fileCount++; + this.methodCall = Util.mergeHashTable(this.methodCall, statistics.methodCall); + this.lineCounter = Util.mergeHashTable(this.lineCounter, statistics.lineCounter); + this.depCounter = Util.mergeHashTable(this.depCounter, statistics.depCounter); + this.parameters = Util.mergeHashTable(this.parameters, statistics.parameters); + this.cycloCounter = Util.mergeHashTable(this.cycloCounter, statistics.cycloCounter); + this.fieldCounter = Util.mergeHashTable(this.fieldCounter, statistics.fieldCounter); + this.methodCounter = Util.mergeHashTable(this.methodCounter, statistics.methodCounter); + this.sFieldCounter = Util.mergeHashTable(this.sFieldCounter, statistics.sFieldCounter); + this.sMethodCounter = Util.mergeHashTable(this.sMethodCounter, statistics.sMethodCounter); + this.anonymousClasses += statistics.anonymousClasses; + if(statistics.anonymousClasses > this.anonymousClasses_max) this.anonymousClasses_max = statistics.anonymousClasses; + this.interfaces += statistics.interfaces; + if(statistics.interfaces > this.interfaces_max) this.interfaces_max = statistics.interfaces; + this.classes += statistics.classes; + if(statistics.classes > this.classes_max) this.classes_max = statistics.classes; + this.totalCode += statistics.totalCode; + if(statistics.totalCode > this.totalCode_max) this.totalCode_max = statistics.totalCode; + this.compilationUnits += statistics.compilationUnits; + } + + public void clear() { + this.methodCall.clear(); + this.lineCounter.clear(); + this.depCounter.clear(); + this.parameters.clear(); + this.cycloCounter.clear(); + this.fieldCounter.clear(); + this.methodCounter.clear(); + this.sFieldCounter.clear(); + this.sMethodCounter.clear(); + this.anonymousClasses = 0; + this.anonymousClasses_max = 0; + this.interfaces = 0; + this.interfaces_max = 0; + this.classes = 0; + this.classes_max = 0; + this.totalCode = 0; + this.totalCode_max = 0; + this.compilationUnits = 0; + } + + @Override + public String toString() { + return "FOUT: " + methodCall + "\n" + + "MLOC: " + lineCounter + "\n" + + "NBD: " + depCounter + "\n" + + "PAR: " + parameters + "\n" + + "VG: " + cycloCounter + "\n" + + + "NOF: " + fieldCounter + "\n" + + "NOM: " + methodCounter + "\n" + + "NSF: " + sFieldCounter + "\n" + + "NSM: " + sMethodCounter + "\n" + + + "ACD: " + anonymousClasses + "\n" + + "NOI: " + interfaces + "\n" + + "NOT: " + classes + "\n" + + "TLOC: " + totalCode + "\n" + + "NOCU: " + compilationUnits; + } +} diff --git a/src/java/main/br/ufpe/cin/groundhog/metrics/StatisticsTable.java b/src/java/main/br/ufpe/cin/groundhog/metrics/StatisticsTable.java new file mode 100644 index 0000000..61ac5db --- /dev/null +++ b/src/java/main/br/ufpe/cin/groundhog/metrics/StatisticsTable.java @@ -0,0 +1,103 @@ +package br.ufpe.cin.groundhog.metrics; + +import com.google.gson.annotations.SerializedName; + +public abstract class StatisticsTable { + + //Values for file level + @SerializedName("metric_fout_avg") + public double FOUT_avg; + @SerializedName("metric_fout_max") + public long FOUT_max; + @SerializedName("metric_fout_sum") + public long FOUT_sum; + + @SerializedName("metric_mloc_avg") + public double MLOC_avg; + @SerializedName("metric_mloc_max") + public long MLOC_max; + @SerializedName("metric_mloc_sum") + public long MLOC_sum; + + @SerializedName("metric_nbd_avg") + public double NBD_avg; + @SerializedName("metric_nbd_max") + public long NBD_max; + @SerializedName("metric_nbd_sum") + public long NBD_sum; + + @SerializedName("metric_nof_avg") + public double NOF_avg; + @SerializedName("metric_nof_max") + public long NOF_max; + @SerializedName("metric_nof_sum") + public long NOF_sum; + + @SerializedName("metric_nom_avg") + public double NOM_avg; + @SerializedName("metric_nom_max") + public long NOM_max; + @SerializedName("metric_nom_sum") + public long NOM_sum; + + @SerializedName("metric_nsf_avg") + public double NSF_avg; + @SerializedName("metric_nsf_max") + public long NSF_max; + @SerializedName("metric_nsf_sum") + public long NSF_sum; + + @SerializedName("metric_nsm_avg") + public double NSM_avg; + @SerializedName("metric_nsm_max") + public long NSM_max; + @SerializedName("metric_nsm_sum") + public long NSM_sum; + + @SerializedName("metric_par_avg") + public double PAR_avg; + @SerializedName("metric_par_max") + public long PAR_max; + @SerializedName("metric_par_sum") + public long PAR_sum; + + @SerializedName("metric_vg_avg") + public double VG_avg; + @SerializedName("metric_vg_max") + public long VG_max; + @SerializedName("metric_vg_sum") + public long VG_sum; + + @Override + public String toString() { + return + "metric_fout_avg: " + FOUT_avg + "\n"+ + "metric_fout_max: " + FOUT_max + "\n"+ + "metric_fout_sum: " + FOUT_sum + "\n"+ + "metric_mloc_avg: " + MLOC_avg + "\n"+ + "metric_mloc_max: " + MLOC_max + "\n"+ + "metric_mloc_sum: " + MLOC_sum + "\n"+ + "metric_nbd_avg: " + NBD_avg + "\n"+ + "metric_nbd_max: " + NBD_max + "\n"+ + "metric_nbd_sum: " + NBD_sum + "\n"+ + "metric_nof_avg: " + NOF_avg + "\n"+ + "metric_nof_max: " + NOF_max + "\n"+ + "metric_nof_sum: " + NOF_sum + "\n"+ + "metric_nom_avg: " + NOM_avg + "\n"+ + "metric_nom_max: " + NOM_max + "\n"+ + "metric_nom_sum: " + NOM_sum + "\n"+ + "metric_nsf_avg: " + NSF_avg + "\n"+ + "metric_nsf_max: " + NSF_max + "\n"+ + "metric_nsf_sum: " + NSF_sum + "\n"+ + "metric_nsm_avg: " + NSM_avg + "\n"+ + "metric_nsm_max: " + NSM_max + "\n"+ + "metric_nsm_sum: " + NSM_sum + "\n"+ + "metric_par_avg: " + PAR_avg + "\n"+ + "metric_par_max: " + PAR_max + "\n"+ + "metric_par_sum: " + PAR_sum + "\n"+ + "metric_vg_avg: " + VG_avg + "\n"+ + "metric_vg_max: " + VG_max + "\n"+ + "metric_vg_sum: " + VG_sum + "\n"; + } + +} \ No newline at end of file diff --git a/src/java/main/br/ufpe/cin/groundhog/metrics/StatisticsTableFile.java b/src/java/main/br/ufpe/cin/groundhog/metrics/StatisticsTableFile.java new file mode 100644 index 0000000..cedeb58 --- /dev/null +++ b/src/java/main/br/ufpe/cin/groundhog/metrics/StatisticsTableFile.java @@ -0,0 +1,37 @@ +package br.ufpe.cin.groundhog.metrics; + +import org.bson.types.ObjectId; +import org.mongodb.morphia.annotations.Entity; +import org.mongodb.morphia.annotations.Id; +import org.mongodb.morphia.annotations.Indexed; + +import com.google.gson.annotations.SerializedName; + +@Entity("statisticstablefile") +public class StatisticsTableFile extends StatisticsTable{ + + @Id + @Indexed(unique=true, dropDups=true) + ObjectId id; + + @SerializedName("metric_acd") + public long ACD; + + @SerializedName("metric_noi") + public long NOI; + + @SerializedName("metric_not") + public long NOT; + + @SerializedName("metric_tloc") + public long TLOC; + + @Override + public String toString() { + return super.toString() + + "metric_acd: " + ACD + "\n" + + "metric_noi: " + NOI + "\n" + + "metric_not: " + NOT + "\n" + + "metric_tloc: " + TLOC; + } +} diff --git a/src/java/main/br/ufpe/cin/groundhog/metrics/StatisticsTablePackage.java b/src/java/main/br/ufpe/cin/groundhog/metrics/StatisticsTablePackage.java new file mode 100644 index 0000000..886cb5b --- /dev/null +++ b/src/java/main/br/ufpe/cin/groundhog/metrics/StatisticsTablePackage.java @@ -0,0 +1,66 @@ +package br.ufpe.cin.groundhog.metrics; + +import org.bson.types.ObjectId; +import org.mongodb.morphia.annotations.Entity; +import org.mongodb.morphia.annotations.Id; +import org.mongodb.morphia.annotations.Indexed; + +import com.google.gson.annotations.SerializedName; + +@Entity("statisticstablepackage") +public class StatisticsTablePackage extends StatisticsTable{ + + @Id + @Indexed(unique=true, dropDups=true) + ObjectId id; + + @SerializedName("metric_nocu") + public long NOCU; + + @SerializedName("metric_acd_avg") + public double ACD_avg; + @SerializedName("metric_acd_max") + public long ACD_max; + @SerializedName("metric_acd_sum") + public long ACD_sum; + + @SerializedName("metric_noi_avg") + public double NOI_avg; + @SerializedName("metric_noi_max") + public long NOI_max; + @SerializedName("metric_noi_sum") + public long NOI_sum; + + @SerializedName("metric_not_avg") + public double NOT_avg; + @SerializedName("metric_not_max") + public long NOT_max; + @SerializedName("metric_not_sum") + public long NOT_sum; + + @SerializedName("metric_tloc_avg") + public double TLOC_avg; + @SerializedName("metric_tloc_max") + public long TLOC_max; + @SerializedName("metric_tloc_sum") + public long TLOC_sum; + + @Override + public String toString() { + return super.toString() + + "metric_acd_avg: " + ACD_avg + "\n" + + "metric_acd_max: " + ACD_max + "\n" + + "metric_acd_sum: " + ACD_sum + "\n" + + "metric_noi_avg: " + NOI_avg + "\n" + + "metric_noi_max: " + NOI_max + "\n" + + "metric_noi_sum: " + NOI_sum + "\n" + + "metric_not_avg: " + NOT_avg + "\n" + + "metric_not_max: " + NOT_max + "\n" + + "metric_not_sum: " + NOT_sum + "\n" + + "metric_tloc_avg: " + TLOC_avg + "\n" + + "metric_tloc_max: " + TLOC_max + "\n" + + "metric_tloc_sum: " + TLOC_sum + "\n" + + "metric_nocu: " + NOCU; + } + +} diff --git a/src/java/main/br/ufpe/cin/groundhog/metrics/Test.java b/src/java/main/br/ufpe/cin/groundhog/metrics/Test.java new file mode 100644 index 0000000..3ec1760 --- /dev/null +++ b/src/java/main/br/ufpe/cin/groundhog/metrics/Test.java @@ -0,0 +1,155 @@ +package br.ufpe.cin.groundhog.metrics; + +import java.io.*; +import java.util.Hashtable; +import java.util.LinkedHashSet; +import java.util.Map; +import java.util.Set; + +import org.apache.log4j.Logger; +import org.eclipse.jdt.core.JavaCore; +import org.eclipse.jdt.core.dom.*; + +public class Test { + + public static final String VERSION_1_4 = "1.4"; + public static final String VERSION_1_5 = "1.5"; + public static final String VERSION_1_6 = "1.6"; + public static final String VERSION_1_7 = "1.7"; + + private static final Set ALLOWED_TARGET_JDKS = new LinkedHashSet(); + static { + ALLOWED_TARGET_JDKS.add(VERSION_1_4); + ALLOWED_TARGET_JDKS.add(VERSION_1_5); + ALLOWED_TARGET_JDKS.add(VERSION_1_6); + ALLOWED_TARGET_JDKS.add(VERSION_1_7); + } + + private static final Logger log = Logger.getLogger(Test.class); + public static boolean DEBUG; + + private String targetJdk = VERSION_1_4; + private String encoding = "UTF-8"; + + public void setTargetJdk( String targetJdk ) { + if(!ALLOWED_TARGET_JDKS.contains(targetJdk)) + throw new IllegalArgumentException("Invalid value for targetJdk: [" + targetJdk + "]. Allowed are "+ALLOWED_TARGET_JDKS); + + this.targetJdk = targetJdk; + } + + public void setEncoding( String encoding ) { + if( encoding == null ) + throw new IllegalArgumentException("encoding is null"); + if( encoding.trim().length() == 0 ) + throw new IllegalArgumentException("encoding is empty"); + this.encoding = encoding; + } + + public GroundhogASTVisitor visitFile( File file ) throws IOException { + if(!file.exists()) + new IllegalArgumentException("File "+file.getAbsolutePath()+" doesn't exist"); + + String source = readFileToString( file, encoding ); + + return visitString( source ); + } + + public static String readFileToString( File file, String encoding ) throws IOException { + FileInputStream stream = new FileInputStream( file ); + String result = null; + try { + result = readInputStreamToString( stream, encoding ); + } finally { + try { + stream.close(); + } catch (IOException e) { + // ignore + } + } + return result; + } + + public GroundhogASTVisitor visit( InputStream stream, String encoding ) throws IOException { + if( stream == null ) + throw new IllegalArgumentException("stream is null"); + if( encoding == null ) + throw new IllegalArgumentException("encoding is null"); + if( encoding.trim().length() == 0 ) + throw new IllegalArgumentException("encoding is empty"); + + String source = readInputStreamToString( stream, encoding ); + + return visitString( source ); + } + + public static String readInputStreamToString( InputStream stream, String encoding ) throws IOException { + + Reader r = new BufferedReader( new InputStreamReader( stream, encoding ), 16384 ); + StringBuilder result = new StringBuilder(16384); + char[] buffer = new char[16384]; + + int len; + while((len = r.read( buffer, 0, buffer.length )) >= 0) { + result.append(buffer, 0, len); + } + + return result.toString(); + } + + public GroundhogASTVisitor visitString( String source ) { + ASTParser parser = ASTParser.newParser(AST.JLS3); + + @SuppressWarnings( "unchecked" ) + Map options = JavaCore.getOptions(); + if(VERSION_1_5.equals(targetJdk)) + JavaCore.setComplianceOptions(JavaCore.VERSION_1_5, options); + else if(VERSION_1_6.equals(targetJdk)) + JavaCore.setComplianceOptions(JavaCore.VERSION_1_6, options); + else if(VERSION_1_7.equals(targetJdk)) + JavaCore.setComplianceOptions(JavaCore.VERSION_1_7, options); + else { + if(!VERSION_1_4.equals(targetJdk)) { + log.warn("Unknown targetJdk ["+targetJdk+"]. Using "+VERSION_1_4+" for parsing. Supported values are: " + + VERSION_1_4 + ", " + + VERSION_1_5 + ", " + + VERSION_1_6 + ); + } + JavaCore.setComplianceOptions(JavaCore.VERSION_1_4, options); + } + parser.setCompilerOptions(options); + + parser.setResolveBindings(false); + parser.setStatementsRecovery(false); + parser.setBindingsRecovery(false); + parser.setSource(source.toCharArray()); + //parser.setIgnoreMethodBodies(false); + + CompilationUnit ast = (CompilationUnit) parser.createAST(null); + + // AstVisitor extends org.eclipse.jdt.core.dom.ASTVisitor + GroundhogASTVisitor visitor = new GroundhogASTVisitor(); + Statistics statistics = new Statistics(); + visitor.setStatistics(statistics); + ast.accept( visitor ); + + return visitor; + } + + public static void main(String []args) throws IOException{ + System.out.println("Vai começar!"); + Test test = new Test(); + File file = new File("/home/bruno/scm/github.com/groundhog2/src/java/main/br/ufpe/cin/groundhog/metrics/Test3.java"); + if (file.isFile()){ + GroundhogASTVisitor visitor = test.visitFile(file); + visitor.toString(); + System.out.println(visitor.getStatistics()); + }else{ + System.out.println("Is not a file!"); + } + + Hashtable table = new Hashtable(); + + } +} diff --git a/src/java/main/br/ufpe/cin/groundhog/metrics/Test3.java b/src/java/main/br/ufpe/cin/groundhog/metrics/Test3.java new file mode 100644 index 0000000..dedf81f --- /dev/null +++ b/src/java/main/br/ufpe/cin/groundhog/metrics/Test3.java @@ -0,0 +1,96 @@ +package br.ufpe.cin.groundhog.metrics; + +import java.io.File; +import java.util.ArrayList; + +import br.ufpe.cin.groundhog.extractor.GitCommitExtractor; + +public class Test3 { + + enum lol { + + } + + public void zoeira1(String k, String i, String j){ + System.out.println("HAHAHAHAH"); + System.out.println("HAHAHAHAH"); + System.out.println("HAHAHAHAH"); + System.out.println("HAHAHAHAH"); + System.out.println("HAHAHAHAH"); + } + + public void zoeira(String ki, String i){ + try { + int k = 0; + synchronized (this) { + do{ + System.out.println("Testando, testando, testando, tetetetetestando!"); + + ArrayList arr = new ArrayList(){ + + @Override + public String toString() { + + int nnumber = 10; + + while(nnumber != 0){ + + try { + + super.toString(); + nnumber--; + } catch (ArrayIndexOutOfBoundsException e){ + if(nnumber == 0){ + System.out.println("Zoeira never ends"); + }else{ + System.out.println("kkkkkk"); + } + } catch (NullPointerException e){ + } catch (Exception e) { + // TODO: handle exception + } + } + return super.toString(); + + } + }; + }while(k++<10); + } + } catch (Exception e) { + // TODO: handle exception + } + System.out.println("Testando, testando, testando, tetetetetestando!"); + System.out.println("Testando, testando, testando, tetetetetestando!"); + System.out.println("Testando, testando, testando, tetetetetestando!"); + System.out.println("Testando, testando, testando, tetetetetestando!"); +// System.out.println("Testando, testando, testando, tetetetetestando!"); +// System.out.println("Testando, testando, testando, tetetetetestando!"); +// System.out.println("Testando, testando, testando, tetetetetestando!"); +// System.out.println("Testando, testando, testando, tetetetetestando!"); +// System.out.println("Testando, testando, testando, tetetetetestando!"); +// System.out.println("Testando, testando, testando, tetetetetestando!"); +// System.out.println("Testando, testando, testando, tetetetetestando!"); +// System.out.println("Testando, testando, testando, tetetetetestando!"); +// System.out.println("Testando, testando, testando, tetetetetestando!"); +// System.out.println("Testando, testando, testando, tetetetetestando!"); +// System.out.println("Testando, testando, testando, tetetetetestando!"); + } + + public void zoeira2(String k, String i,String ki, String ii){ + if(true){ + if(true){ + System.out.println("Testando, testando, testando, tetetetetestando!"); + } + } + } + + public static void main(String[] args) { + GitCommitExtractor extractor = new GitCommitExtractor(); + File file = new File("/home/bruno/scm/github.com/learnhaskell"); + if(file.isDirectory()){ + extractor.extractCommits(file); + extractor.extractCommits(file); + } + + } +} diff --git a/src/java/main/br/ufpe/cin/groundhog/metrics/Teste2.java b/src/java/main/br/ufpe/cin/groundhog/metrics/Teste2.java new file mode 100644 index 0000000..9595d2e --- /dev/null +++ b/src/java/main/br/ufpe/cin/groundhog/metrics/Teste2.java @@ -0,0 +1,25 @@ +package br.ufpe.cin.groundhog.metrics; + +import java.net.UnknownHostException; + +import br.ufpe.cin.groundhog.database.GroundhogDB; +import br.ufpe.cin.groundhog.metrics.exception.InvalidJavaFileException; +import br.ufpe.cin.groundhog.metrics.exception.InvalidJavaProjectPathException; +import br.ufpe.cin.groundhog.metrics.exception.InvalidSourceRootCodePathException; +import br.ufpe.cin.groundhog.metrics.exception.InvalidTestSourcePathException; + +public class Teste2 { + + public static void main(String[] args) throws InvalidJavaProjectPathException, InvalidSourceRootCodePathException, InvalidTestSourcePathException, InvalidJavaFileException, UnknownHostException { + GroundhogDB ghdb = new GroundhogDB("127.0.0.1", "java_metrics"); + ghdb.getMapper().mapPackage("br.ufpe.cin.groundhog.metrics"); + + JavaFile j = new JavaFile("oi"); + JavaProject project = new JavaProject("src/main/resources/scribe-java/"); + project.generateStructure("src/main", "src/test"); + System.out.println("Scanning packages to project:"); + System.out.println(project.toString()); + System.out.println("################################################"); + project.generateMetrics(true,ghdb); + } +} diff --git a/src/java/main/br/ufpe/cin/groundhog/metrics/TesteMongoDB.java b/src/java/main/br/ufpe/cin/groundhog/metrics/TesteMongoDB.java new file mode 100644 index 0000000..0e3be88 --- /dev/null +++ b/src/java/main/br/ufpe/cin/groundhog/metrics/TesteMongoDB.java @@ -0,0 +1,42 @@ +package br.ufpe.cin.groundhog.metrics; + +import java.net.UnknownHostException; +import java.util.List; + +import org.mongodb.morphia.Key; + +import br.ufpe.cin.groundhog.database.GroundhogDB; +import br.ufpe.cin.groundhog.metrics.exception.InvalidJavaFileException; + +import com.mongodb.DB; +import com.mongodb.DBObject; + +public class TesteMongoDB { + + public static void main(String[] args) throws UnknownHostException, InvalidJavaFileException { +// String dbName = "java_metrics"; +// MongoClient client = new MongoClient("127.0.0.1"); +// Morphia morphia = new Morphia(); +// Datastore datastore = morphia.createDatastore(client, dbName); + //DB db = ghdb.getMongo().getDB("java_metrics"); + + GroundhogDB ghdb = new GroundhogDB("127.0.0.1", "java_metrics"); + ghdb.getMapper().mapPackage("br.ufpe.cin.groundhog.metrics"); + + JavaFile file = new JavaFile("/home/bruno/scm/github.com/groundhog2/src/java/main/br/ufpe/cin/groundhog/metrics/JavaFile.java"); + JavaFile file2 = new JavaFile("/home/bruno/scm/github.com/groundhog2/src/java/main/br/ufpe/cin/groundhog/metrics/JavaPackage.java"); + StatisticsTableFile table = new StatisticsTableFile(); +// DBObject object = ghdb.getMapper().toDBObject(file); + //DBObject object2 = ghdb.getMapper().toDBObject(file2); +// System.out.println(db.getCollection("files").save(object)); + + Key key_f = ghdb.save(table); + + file2.setTable(table); + + Key key_jf = ghdb.save(file2); + System.out.println(key_jf); + + + } +} diff --git a/src/java/main/br/ufpe/cin/groundhog/metrics/Util.java b/src/java/main/br/ufpe/cin/groundhog/metrics/Util.java new file mode 100644 index 0000000..f54d834 --- /dev/null +++ b/src/java/main/br/ufpe/cin/groundhog/metrics/Util.java @@ -0,0 +1,108 @@ +package br.ufpe.cin.groundhog.metrics; + +import java.math.BigDecimal; +import java.math.RoundingMode; +import java.util.HashSet; +import java.util.Hashtable; +import java.util.Map; +import java.util.Stack; + +import org.eclipse.jdt.core.ToolFactory; +import org.eclipse.jdt.core.compiler.IScanner; +import org.eclipse.jdt.core.compiler.ITerminalSymbols; +import org.eclipse.jdt.core.compiler.InvalidInputException; + +public class Util { + + /** + * Merge Hashtable ht2 onto ht1 + * @param ht1 + * @param ht2 + */ + public static Hashtable mergeHashTable(Hashtable ht1, Hashtable ht2){ + for (Map.Entry map : ht2.entrySet()){ + if(ht1.containsKey(map.getKey())){ + Util.safeAddToHashTable(ht1, map.getKey(), map.getValue()); + }else{ + ht1.put(map.getKey(), map.getValue()); + } + } + + return ht1; + } + + public static void safeAddToHashTable(Hashtable table,int position){ + + if(table.containsKey(position)){ + table.put(position, table.get(position)+1); + }else{ + table.put(position, 1); + } + } + + public static void safeAddToHashTable(Hashtable table, int key, int value){ + + if(table.containsKey(key)){ + table.put(key, table.get(key)+value); + }else{ + table.put(key, value); + } + } + + /** + * Safe add the passed value to the top element of a stack + * @param stack + * @param value + * @return + */ + public static int safeAddStackTop(Stack stack, int value){ + + int to_return = 0; + + if(!stack.empty()){ + to_return = stack.pop(); + stack.push(to_return+value); + } + + return to_return; + } + + + public static int countCodeLines(String source){ + String temp = source.trim(); + //Because we can get many tokens from the same line and JDT compiler removes all + //space, comment and line break in scanner, we need to create a Set to unique store + //the line number of tokens and get total of line codes + HashSet set = new HashSet<>(); + //We need to process the file without whiteSpace and Commenst, but with the rest + IScanner scanner = ToolFactory.createScanner(false,false,true,true); + scanner.setSource(temp.toCharArray()); + int token = 0x00; + + //While don't reach the end of file count the number of lines + try { + + do{ + + //Get the next token + token = scanner.getNextToken(); + //And them process your line number + set.add(new Integer(scanner.getLineNumber(scanner.getCurrentTokenStartPosition()))); + + }while(token != ITerminalSymbols.TokenNameEOF); + } catch (InvalidInputException e) { + return 0; + } + return set.size(); + } + + public static double safeCalculateAvg(long numerator, long denominator){ + + BigDecimal bNumerator = new BigDecimal(numerator); + BigDecimal bDenominator = new BigDecimal(denominator); + + if (denominator !=0) return bNumerator.divide(bDenominator,10,RoundingMode.HALF_EVEN).doubleValue(); + else return 0; + } + +} diff --git a/src/java/main/br/ufpe/cin/groundhog/metrics/exception/InvalidJavaFileException.java b/src/java/main/br/ufpe/cin/groundhog/metrics/exception/InvalidJavaFileException.java new file mode 100644 index 0000000..61ba52f --- /dev/null +++ b/src/java/main/br/ufpe/cin/groundhog/metrics/exception/InvalidJavaFileException.java @@ -0,0 +1,15 @@ +package br.ufpe.cin.groundhog.metrics.exception; + +import br.ufpe.cin.groundhog.GroundhogException; + +public class InvalidJavaFileException extends GroundhogException { + + /** + * + */ + private static final long serialVersionUID = -7197149220798206965L; + private static final String message = "Invalid Java File path\nPlease check you project structure"; + + public InvalidJavaFileException() { super(InvalidJavaFileException.message); } + public InvalidJavaFileException(String message, Throwable cause) { super(InvalidJavaFileException.message, cause); } +} diff --git a/src/java/main/br/ufpe/cin/groundhog/metrics/exception/InvalidJavaProjectPathException.java b/src/java/main/br/ufpe/cin/groundhog/metrics/exception/InvalidJavaProjectPathException.java new file mode 100644 index 0000000..0ff3b86 --- /dev/null +++ b/src/java/main/br/ufpe/cin/groundhog/metrics/exception/InvalidJavaProjectPathException.java @@ -0,0 +1,18 @@ +package br.ufpe.cin.groundhog.metrics.exception; + +import br.ufpe.cin.groundhog.GroundhogException; + +public class InvalidJavaProjectPathException extends GroundhogException { + + /** + * If an invalid Java path has passed this exception will be raised + * @author Bruno Soares + * @since 0.1.0 + */ + + private static final long serialVersionUID = 7505823601337916084L; + private static final String message = "Invalid Java project path"; + + public InvalidJavaProjectPathException() { super(InvalidJavaProjectPathException.message); } + public InvalidJavaProjectPathException(String message, Throwable cause) { super(InvalidJavaProjectPathException.message, cause); } +} diff --git a/src/java/main/br/ufpe/cin/groundhog/metrics/exception/InvalidSourceRootCodePathException.java b/src/java/main/br/ufpe/cin/groundhog/metrics/exception/InvalidSourceRootCodePathException.java new file mode 100644 index 0000000..26a261a --- /dev/null +++ b/src/java/main/br/ufpe/cin/groundhog/metrics/exception/InvalidSourceRootCodePathException.java @@ -0,0 +1,19 @@ +package br.ufpe.cin.groundhog.metrics.exception; + +import br.ufpe.cin.groundhog.GroundhogException; + +public class InvalidSourceRootCodePathException extends GroundhogException { + + /** + * If an invalid Java path has passed this exception will be raised + * @author Bruno Soares + * @since 0.1.0 + */ + + private static final long serialVersionUID = 476505897031339694L; + private static final String message = "Invalid source root code path"; + + public InvalidSourceRootCodePathException() { super(InvalidSourceRootCodePathException.message); } + public InvalidSourceRootCodePathException(String message, Throwable cause) { super(InvalidSourceRootCodePathException.message, cause); } + +} diff --git a/src/java/main/br/ufpe/cin/groundhog/metrics/exception/InvalidTestSourcePathException.java b/src/java/main/br/ufpe/cin/groundhog/metrics/exception/InvalidTestSourcePathException.java new file mode 100644 index 0000000..26360c8 --- /dev/null +++ b/src/java/main/br/ufpe/cin/groundhog/metrics/exception/InvalidTestSourcePathException.java @@ -0,0 +1,18 @@ +package br.ufpe.cin.groundhog.metrics.exception; + +import br.ufpe.cin.groundhog.GroundhogException; + +public class InvalidTestSourcePathException extends GroundhogException{ + + /** + * If an invalid Java path has passed this exception will be raised + * @author Bruno Soares + * @since 0.1.0 + */ + + private static final long serialVersionUID = 2361880567057134357L; + private static final String message = "Invalid test source root code"; + + public InvalidTestSourcePathException() { super(InvalidTestSourcePathException.message); } + public InvalidTestSourcePathException(String message, Throwable cause) { super(InvalidTestSourcePathException.message, cause); } +} diff --git a/src/java/test/br/ufpe/cin/groundhog/metrics/GenerateMetricsWithoutPersistenceTest.java b/src/java/test/br/ufpe/cin/groundhog/metrics/GenerateMetricsWithoutPersistenceTest.java new file mode 100644 index 0000000..751636d --- /dev/null +++ b/src/java/test/br/ufpe/cin/groundhog/metrics/GenerateMetricsWithoutPersistenceTest.java @@ -0,0 +1,30 @@ +package br.ufpe.cin.groundhog.metrics; + +import static org.junit.Assert.*; + +import org.junit.Test; + +import br.ufpe.cin.groundhog.metrics.exception.InvalidJavaFileException; +import br.ufpe.cin.groundhog.metrics.exception.InvalidJavaProjectPathException; +import br.ufpe.cin.groundhog.metrics.exception.InvalidSourceRootCodePathException; +import br.ufpe.cin.groundhog.metrics.exception.InvalidTestSourcePathException; + +public class GenerateMetricsWithoutPersistenceTest { + + @Test + public void test() { + try { + JavaProject project = new JavaProject("src/main/resources/scribe-java-project/"); + project.generateStructure("src/main/", "src/test/"); + project.generateMetrics(false); + long linesOfCode = 0; + for (JavaPackage table : project.getCode_packages()){ + linesOfCode += table.getTable().TLOC_sum; + } + assertEquals("There should be 2808 lines of code in the source mais code", 2808, linesOfCode); + } catch (InvalidJavaProjectPathException | InvalidSourceRootCodePathException | InvalidTestSourcePathException | InvalidJavaFileException e) { + fail("An exception has occurred!"); + } + } + +} diff --git a/src/java/test/br/ufpe/cin/groundhog/metrics/InvalidJavaFileExceptionTest.java b/src/java/test/br/ufpe/cin/groundhog/metrics/InvalidJavaFileExceptionTest.java new file mode 100644 index 0000000..e885728 --- /dev/null +++ b/src/java/test/br/ufpe/cin/groundhog/metrics/InvalidJavaFileExceptionTest.java @@ -0,0 +1,22 @@ +package br.ufpe.cin.groundhog.metrics; + +import static org.junit.Assert.*; +import static org.junit.matchers.JUnitMatchers.containsString; + +import org.junit.Test; + +import br.ufpe.cin.groundhog.metrics.exception.InvalidJavaFileException; + +public class InvalidJavaFileExceptionTest { + + @Test + public void testInvalidJavaFileException() { + try { + new JavaFile("invalid/path/"); + fail("Should have thrown an InvalidJavaFileException because the java file path is invalid!"); + } catch (InvalidJavaFileException e) { + assertThat(e.getMessage(), containsString("Invalid Java File path\nPlease check you project structure")); + } + } + +} diff --git a/src/java/test/br/ufpe/cin/groundhog/metrics/InvalidJavaProjectPathExceptionTest.java b/src/java/test/br/ufpe/cin/groundhog/metrics/InvalidJavaProjectPathExceptionTest.java new file mode 100644 index 0000000..b51ed72 --- /dev/null +++ b/src/java/test/br/ufpe/cin/groundhog/metrics/InvalidJavaProjectPathExceptionTest.java @@ -0,0 +1,22 @@ +package br.ufpe.cin.groundhog.metrics; + +import static org.junit.Assert.assertThat; +import static org.junit.Assert.fail; +import static org.junit.matchers.JUnitMatchers.containsString; + +import org.junit.Test; + +import br.ufpe.cin.groundhog.metrics.exception.InvalidJavaProjectPathException; + +public class InvalidJavaProjectPathExceptionTest { + + @Test + public void testInvalidJavaProjectPathException() { + try { + new JavaProject("/invalid/path/"); + fail("Should have thrown an InvalidJavaProjectPathException because the project path is invalid!"); + }catch(InvalidJavaProjectPathException e) { + assertThat(e.getMessage(), containsString("Invalid Java project path")); + } + } +} \ No newline at end of file diff --git a/src/java/test/br/ufpe/cin/groundhog/metrics/InvalidSourceRootCodePathExceptionTest.java b/src/java/test/br/ufpe/cin/groundhog/metrics/InvalidSourceRootCodePathExceptionTest.java new file mode 100644 index 0000000..7714965 --- /dev/null +++ b/src/java/test/br/ufpe/cin/groundhog/metrics/InvalidSourceRootCodePathExceptionTest.java @@ -0,0 +1,32 @@ +package br.ufpe.cin.groundhog.metrics; + +import static org.junit.Assert.assertThat; +import static org.junit.Assert.fail; +import static org.junit.matchers.JUnitMatchers.containsString; + +import org.junit.Test; + +import br.ufpe.cin.groundhog.metrics.exception.InvalidJavaFileException; +import br.ufpe.cin.groundhog.metrics.exception.InvalidJavaProjectPathException; +import br.ufpe.cin.groundhog.metrics.exception.InvalidSourceRootCodePathException; +import br.ufpe.cin.groundhog.metrics.exception.InvalidTestSourcePathException; + +public class InvalidSourceRootCodePathExceptionTest { + + @Test + public void testInvalidSourceRootCodePathException() { + try { + JavaProject jp = new JavaProject("src/main/resources/scribe-java-project/"); + jp.generateStructure("invalid/path/", "src/test/"); + fail("Should have thrown an InvalidSourceRootCodePathException because the source root code path is invalid!"); + }catch(InvalidSourceRootCodePathException e) { + assertThat(e.getMessage(), containsString("Invalid source root code path")); + } catch (InvalidJavaProjectPathException e) { + fail("Should have thrown an InvalidSourceRootCodePathException, but another exception was thrown!"); + } catch (InvalidTestSourcePathException e) { + fail("Should have thrown an InvalidSourceRootCodePathException, but another exception was thrown!"); + } catch (InvalidJavaFileException e) { + fail("Should have thrown an InvalidSourceRootCodePathException, but another exception was thrown!"); + } + } +} \ No newline at end of file diff --git a/src/java/test/br/ufpe/cin/groundhog/metrics/InvalidTestSourcePathExceptionTest.java b/src/java/test/br/ufpe/cin/groundhog/metrics/InvalidTestSourcePathExceptionTest.java new file mode 100644 index 0000000..6e1fd86 --- /dev/null +++ b/src/java/test/br/ufpe/cin/groundhog/metrics/InvalidTestSourcePathExceptionTest.java @@ -0,0 +1,32 @@ +package br.ufpe.cin.groundhog.metrics; + +import static org.junit.Assert.assertThat; +import static org.junit.Assert.fail; +import static org.junit.matchers.JUnitMatchers.containsString; + +import org.junit.Test; + +import br.ufpe.cin.groundhog.metrics.exception.InvalidJavaFileException; +import br.ufpe.cin.groundhog.metrics.exception.InvalidJavaProjectPathException; +import br.ufpe.cin.groundhog.metrics.exception.InvalidSourceRootCodePathException; +import br.ufpe.cin.groundhog.metrics.exception.InvalidTestSourcePathException; + +public class InvalidTestSourcePathExceptionTest { + + @Test + public void testInvalidTestSourcePathException() { + try { + JavaProject jp = new JavaProject("src/main/resources/scribe-java-project/"); + jp.generateStructure("src/main/", "invalid/path/"); + fail("Should have thrown an InvalidTestSourcePathException because the test path is invalid!"); + }catch(InvalidTestSourcePathException e) { + assertThat(e.getMessage(), containsString("Invalid test source root code")); + } catch (InvalidJavaProjectPathException e) { + fail("Should have thrown an InvalidTestSourcePathException, but another exception was thrown!"); + } catch (InvalidSourceRootCodePathException e) { + fail("Should have thrown an InvalidTestSourcePathException, but another exception was thrown!"); + } catch (InvalidJavaFileException e) { + fail("Should have thrown an InvalidTestSourcePathException, but another exception was thrown!"); + } + } +} \ No newline at end of file diff --git a/src/main/resources/scribe-java-project/src/main/config/scribe-eclipse-formatter.xml b/src/main/resources/scribe-java-project/src/main/config/scribe-eclipse-formatter.xml new file mode 100644 index 0000000..8ea5bc9 --- /dev/null +++ b/src/main/resources/scribe-java-project/src/main/config/scribe-eclipse-formatter.xml @@ -0,0 +1,290 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/main/resources/scribe-java-project/src/main/config/scribe-eclipse.importorder b/src/main/resources/scribe-java-project/src/main/config/scribe-eclipse.importorder new file mode 100644 index 0000000..1fcaf0f --- /dev/null +++ b/src/main/resources/scribe-java-project/src/main/config/scribe-eclipse.importorder @@ -0,0 +1,7 @@ +#Organize Import Order +#Tue Feb 21 20:29:55 GMT 2012 +4=java +3=javax +2=org +1=org.boncey +0=com diff --git a/src/main/resources/scribe-java-project/src/main/java/org/scribe/builder/ServiceBuilder.java b/src/main/resources/scribe-java-project/src/main/java/org/scribe/builder/ServiceBuilder.java new file mode 100644 index 0000000..27f3c8f --- /dev/null +++ b/src/main/resources/scribe-java-project/src/main/java/org/scribe/builder/ServiceBuilder.java @@ -0,0 +1,169 @@ +package org.scribe.builder; + +import java.io.*; +import org.scribe.builder.api.*; +import org.scribe.exceptions.*; +import org.scribe.model.*; +import org.scribe.oauth.*; +import org.scribe.utils.*; + +/** + * Implementation of the Builder pattern, with a fluent interface that creates a + * {@link OAuthService} + * + * @author Pablo Fernandez + * + */ +public class ServiceBuilder +{ + private String apiKey; + private String apiSecret; + private String callback; + private Api api; + private String scope; + private SignatureType signatureType; + private OutputStream debugStream; + + /** + * Default constructor + */ + public ServiceBuilder() + { + this.callback = OAuthConstants.OUT_OF_BAND; + this.signatureType = SignatureType.Header; + this.debugStream = null; + } + + /** + * Configures the {@link Api} + * + * @param apiClass the class of one of the existent {@link Api}s on org.scribe.api package + * @return the {@link ServiceBuilder} instance for method chaining + */ + public ServiceBuilder provider(Class apiClass) + { + this.api = createApi(apiClass); + return this; + } + + private Api createApi(Class apiClass) + { + Preconditions.checkNotNull(apiClass, "Api class cannot be null"); + Api api; + try + { + api = apiClass.newInstance(); + } + catch(Exception e) + { + throw new OAuthException("Error while creating the Api object", e); + } + return api; + } + + /** + * Configures the {@link Api} + * + * Overloaded version. Let's you use an instance instead of a class. + * + * @param api instance of {@link Api}s + * @return the {@link ServiceBuilder} instance for method chaining + */ + public ServiceBuilder provider(Api api) + { + Preconditions.checkNotNull(api, "Api cannot be null"); + this.api = api; + return this; + } + + /** + * Adds an OAuth callback url + * + * @param callback callback url. Must be a valid url or 'oob' for out of band OAuth + * @return the {@link ServiceBuilder} instance for method chaining + */ + public ServiceBuilder callback(String callback) + { + Preconditions.checkNotNull(callback, "Callback can't be null"); + this.callback = callback; + return this; + } + + /** + * Configures the api key + * + * @param apiKey The api key for your application + * @return the {@link ServiceBuilder} instance for method chaining + */ + public ServiceBuilder apiKey(String apiKey) + { + Preconditions.checkEmptyString(apiKey, "Invalid Api key"); + this.apiKey = apiKey; + return this; + } + + /** + * Configures the api secret + * + * @param apiSecret The api secret for your application + * @return the {@link ServiceBuilder} instance for method chaining + */ + public ServiceBuilder apiSecret(String apiSecret) + { + Preconditions.checkEmptyString(apiSecret, "Invalid Api secret"); + this.apiSecret = apiSecret; + return this; + } + + /** + * Configures the OAuth scope. This is only necessary in some APIs (like Google's). + * + * @param scope The OAuth scope + * @return the {@link ServiceBuilder} instance for method chaining + */ + public ServiceBuilder scope(String scope) + { + Preconditions.checkEmptyString(scope, "Invalid OAuth scope"); + this.scope = scope; + return this; + } + + /** + * Configures the signature type, choose between header, querystring, etc. Defaults to Header + * + * @param scope The OAuth scope + * @return the {@link ServiceBuilder} instance for method chaining + */ + public ServiceBuilder signatureType(SignatureType type) + { + Preconditions.checkNotNull(type, "Signature type can't be null"); + this.signatureType = type; + return this; + } + + public ServiceBuilder debugStream(OutputStream stream) + { + Preconditions.checkNotNull(stream, "debug stream can't be null"); + this.debugStream = stream; + return this; + } + + public ServiceBuilder debug() + { + this.debugStream(System.out); + return this; + } + + /** + * Returns the fully configured {@link OAuthService} + * + * @return fully configured {@link OAuthService} + */ + public OAuthService build() + { + Preconditions.checkNotNull(api, "You must specify a valid api through the provider() method"); + Preconditions.checkEmptyString(apiKey, "You must provide an api key"); + Preconditions.checkEmptyString(apiSecret, "You must provide an api secret"); + return api.createService(new OAuthConfig(apiKey, apiSecret, callback, signatureType, scope, debugStream)); + } +} diff --git a/src/main/resources/scribe-java-project/src/main/java/org/scribe/builder/api/AWeberApi.java b/src/main/resources/scribe-java-project/src/main/java/org/scribe/builder/api/AWeberApi.java new file mode 100644 index 0000000..53ae1fc --- /dev/null +++ b/src/main/resources/scribe-java-project/src/main/java/org/scribe/builder/api/AWeberApi.java @@ -0,0 +1,28 @@ +package org.scribe.builder.api; + +import org.scribe.model.Token; + +public class AWeberApi extends DefaultApi10a +{ + private static final String AUTHORIZE_URL = "https://auth.aweber.com/1.0/oauth/authorize?oauth_token=%s"; + private static final String REQUEST_TOKEN_ENDPOINT = "https://auth.aweber.com/1.0/oauth/request_token"; + private static final String ACCESS_TOKEN_ENDPOINT = "https://auth.aweber.com/1.0/oauth/access_token"; + + @Override + public String getAccessTokenEndpoint() + { + return ACCESS_TOKEN_ENDPOINT; + } + + @Override + public String getRequestTokenEndpoint() + { + return REQUEST_TOKEN_ENDPOINT; + } + + @Override + public String getAuthorizationUrl(Token requestToken) + { + return String.format(AUTHORIZE_URL, requestToken.getToken()); + } +} diff --git a/src/main/resources/scribe-java-project/src/main/java/org/scribe/builder/api/Api.java b/src/main/resources/scribe-java-project/src/main/java/org/scribe/builder/api/Api.java new file mode 100644 index 0000000..6664296 --- /dev/null +++ b/src/main/resources/scribe-java-project/src/main/java/org/scribe/builder/api/Api.java @@ -0,0 +1,25 @@ +package org.scribe.builder.api; + +import org.scribe.model.*; +import org.scribe.oauth.*; + +/** + * Contains all the configuration needed to instantiate a valid {@link OAuthService} + * + * @author Pablo Fernandez + * + */ +public interface Api +{ + /** + * Creates an {@link OAuthService} + * + * @param apiKey your application api key + * @param apiSecret your application api secret + * @param callback the callback url (or 'oob' for out of band OAuth) + * @param scope the OAuth scope + * + * @return fully configured {@link OAuthService} + */ + OAuthService createService(OAuthConfig config); +} diff --git a/src/main/resources/scribe-java-project/src/main/java/org/scribe/builder/api/ConstantContactApi.java b/src/main/resources/scribe-java-project/src/main/java/org/scribe/builder/api/ConstantContactApi.java new file mode 100644 index 0000000..0588bc4 --- /dev/null +++ b/src/main/resources/scribe-java-project/src/main/java/org/scribe/builder/api/ConstantContactApi.java @@ -0,0 +1,26 @@ +package org.scribe.builder.api; + +import org.scribe.model.*; + +public class ConstantContactApi extends DefaultApi10a +{ + private static final String AUTHORIZE_URL = "https://oauth.constantcontact.com/ws/oauth/confirm_access?oauth_token=%s"; + + @Override + public String getAccessTokenEndpoint() + { + return "https://oauth.constantcontact.com/ws/oauth/access_token"; + } + + @Override + public String getAuthorizationUrl(Token requestToken) + { + return String.format(AUTHORIZE_URL, requestToken.getToken()); + } + + @Override + public String getRequestTokenEndpoint() + { + return "https://oauth.constantcontact.com/ws/oauth/request_token"; + } +} diff --git a/src/main/resources/scribe-java-project/src/main/java/org/scribe/builder/api/ConstantContactApi2.java b/src/main/resources/scribe-java-project/src/main/java/org/scribe/builder/api/ConstantContactApi2.java new file mode 100644 index 0000000..b5e4cac --- /dev/null +++ b/src/main/resources/scribe-java-project/src/main/java/org/scribe/builder/api/ConstantContactApi2.java @@ -0,0 +1,55 @@ +package org.scribe.builder.api; + +import java.util.regex.*; +import org.scribe.exceptions.*; +import org.scribe.extractors.*; +import org.scribe.model.*; +import org.scribe.utils.*; + +public class ConstantContactApi2 extends DefaultApi20 +{ + private static final String AUTHORIZE_URL = "https://oauth2.constantcontact.com/oauth2/oauth/siteowner/authorize?client_id=%s&response_type=code&redirect_uri=%s"; + + @Override + public String getAccessTokenEndpoint() + { + return "https://oauth2.constantcontact.com/oauth2/oauth/token?grant_type=authorization_code"; + } + + @Override + public String getAuthorizationUrl(OAuthConfig config) + { + return String.format(AUTHORIZE_URL, config.getApiKey(), OAuthEncoder.encode(config.getCallback())); + } + + @Override + public Verb getAccessTokenVerb() + { + return Verb.POST; + } + + @Override + public AccessTokenExtractor getAccessTokenExtractor() + { + return new AccessTokenExtractor() + { + + public Token extract(String response) + { + Preconditions.checkEmptyString(response, "Response body is incorrect. Can't extract a token from an empty string"); + + String regex = "\"access_token\"\\s*:\\s*\"([^&\"]+)\""; + Matcher matcher = Pattern.compile(regex).matcher(response); + if (matcher.find()) + { + String token = OAuthEncoder.decode(matcher.group(1)); + return new Token(token, "", response); + } + else + { + throw new OAuthException("Response body is incorrect. Can't extract a token from this: '" + response + "'", null); + } + } + }; + } +} \ No newline at end of file diff --git a/src/main/resources/scribe-java-project/src/main/java/org/scribe/builder/api/DefaultApi10a.java b/src/main/resources/scribe-java-project/src/main/java/org/scribe/builder/api/DefaultApi10a.java new file mode 100644 index 0000000..7506986 --- /dev/null +++ b/src/main/resources/scribe-java-project/src/main/java/org/scribe/builder/api/DefaultApi10a.java @@ -0,0 +1,141 @@ +package org.scribe.builder.api; + +import org.scribe.extractors.*; +import org.scribe.model.*; +import org.scribe.oauth.*; +import org.scribe.services.*; + +/** + * Default implementation of the OAuth protocol, version 1.0a + * + * This class is meant to be extended by concrete implementations of the API, + * providing the endpoints and endpoint-http-verbs. + * + * If your Api adheres to the 1.0a protocol correctly, you just need to extend + * this class and define the getters for your endpoints. + * + * If your Api does something a bit different, you can override the different + * extractors or services, in order to fine-tune the process. Please read the + * javadocs of the interfaces to get an idea of what to do. + * + * @author Pablo Fernandez + * + */ +public abstract class DefaultApi10a implements Api +{ + /** + * Returns the access token extractor. + * + * @return access token extractor + */ + public AccessTokenExtractor getAccessTokenExtractor() + { + return new TokenExtractorImpl(); + } + + /** + * Returns the base string extractor. + * + * @return base string extractor + */ + public BaseStringExtractor getBaseStringExtractor() + { + return new BaseStringExtractorImpl(); + } + + /** + * Returns the header extractor. + * + * @return header extractor + */ + public HeaderExtractor getHeaderExtractor() + { + return new HeaderExtractorImpl(); + } + + /** + * Returns the request token extractor. + * + * @return request token extractor + */ + public RequestTokenExtractor getRequestTokenExtractor() + { + return new TokenExtractorImpl(); + } + + /** + * Returns the signature service. + * + * @return signature service + */ + public SignatureService getSignatureService() + { + return new HMACSha1SignatureService(); + } + + /** + * Returns the timestamp service. + * + * @return timestamp service + */ + public TimestampService getTimestampService() + { + return new TimestampServiceImpl(); + } + + /** + * Returns the verb for the access token endpoint (defaults to POST) + * + * @return access token endpoint verb + */ + public Verb getAccessTokenVerb() + { + return Verb.POST; + } + + /** + * Returns the verb for the request token endpoint (defaults to POST) + * + * @return request token endpoint verb + */ + public Verb getRequestTokenVerb() + { + return Verb.POST; + } + + /** + * Returns the URL that receives the request token requests. + * + * @return request token URL + */ + public abstract String getRequestTokenEndpoint(); + + /** + * Returns the URL that receives the access token requests. + * + * @return access token URL + */ + public abstract String getAccessTokenEndpoint(); + + /** + * Returns the URL where you should redirect your users to authenticate + * your application. + * + * @param requestToken the request token you need to authorize + * @return the URL where you should redirect your users + */ + public abstract String getAuthorizationUrl(Token requestToken); + + /** + * Returns the {@link OAuthService} for this Api + * + * @param apiKey Key + * @param apiSecret Api Secret + * @param callback OAuth callback (either URL or 'oob') + * @param scope OAuth scope (optional) + */ + public OAuthService createService(OAuthConfig config) + { + return new OAuth10aServiceImpl(this, config); + } +} diff --git a/src/main/resources/scribe-java-project/src/main/java/org/scribe/builder/api/DefaultApi20.java b/src/main/resources/scribe-java-project/src/main/java/org/scribe/builder/api/DefaultApi20.java new file mode 100644 index 0000000..ffb6207 --- /dev/null +++ b/src/main/resources/scribe-java-project/src/main/java/org/scribe/builder/api/DefaultApi20.java @@ -0,0 +1,70 @@ +package org.scribe.builder.api; + +import org.scribe.extractors.*; +import org.scribe.model.*; +import org.scribe.oauth.*; + +/** + * Default implementation of the OAuth protocol, version 2.0 (draft 11) + * + * This class is meant to be extended by concrete implementations of the API, + * providing the endpoints and endpoint-http-verbs. + * + * If your Api adheres to the 2.0 (draft 11) protocol correctly, you just need to extend + * this class and define the getters for your endpoints. + * + * If your Api does something a bit different, you can override the different + * extractors or services, in order to fine-tune the process. Please read the + * javadocs of the interfaces to get an idea of what to do. + * + * @author Diego Silveira + * + */ +public abstract class DefaultApi20 implements Api +{ + + /** + * Returns the access token extractor. + * + * @return access token extractor + */ + public AccessTokenExtractor getAccessTokenExtractor() + { + return new TokenExtractor20Impl(); + } + + /** + * Returns the verb for the access token endpoint (defaults to GET) + * + * @return access token endpoint verb + */ + public Verb getAccessTokenVerb() + { + return Verb.GET; + } + + /** + * Returns the URL that receives the access token requests. + * + * @return access token URL + */ + public abstract String getAccessTokenEndpoint(); + + /** + * Returns the URL where you should redirect your users to authenticate + * your application. + * + * @param config OAuth 2.0 configuration param object + * @return the URL where you should redirect your users + */ + public abstract String getAuthorizationUrl(OAuthConfig config); + + /** + * {@inheritDoc} + */ + public OAuthService createService(OAuthConfig config) + { + return new OAuth20ServiceImpl(this, config); + } + +} diff --git a/src/main/resources/scribe-java-project/src/main/java/org/scribe/builder/api/DiggApi.java b/src/main/resources/scribe-java-project/src/main/java/org/scribe/builder/api/DiggApi.java new file mode 100644 index 0000000..b69253e --- /dev/null +++ b/src/main/resources/scribe-java-project/src/main/java/org/scribe/builder/api/DiggApi.java @@ -0,0 +1,29 @@ +package org.scribe.builder.api; + +import org.scribe.model.*; + +public class DiggApi extends DefaultApi10a +{ + + private static final String AUTHORIZATION_URL = "http://digg.com/oauth/authorize?oauth_token=%s"; + private static final String BASE_URL = "http://services.digg.com/oauth/"; + + @Override + public String getRequestTokenEndpoint() + { + return BASE_URL + "request_token"; + } + + @Override + public String getAccessTokenEndpoint() + { + return BASE_URL + "access_token"; + } + + @Override + public String getAuthorizationUrl(Token requestToken) + { + return String.format(AUTHORIZATION_URL, requestToken.getToken()); + } + +} diff --git a/src/main/resources/scribe-java-project/src/main/java/org/scribe/builder/api/DropBoxApi.java b/src/main/resources/scribe-java-project/src/main/java/org/scribe/builder/api/DropBoxApi.java new file mode 100644 index 0000000..86f4a71 --- /dev/null +++ b/src/main/resources/scribe-java-project/src/main/java/org/scribe/builder/api/DropBoxApi.java @@ -0,0 +1,25 @@ +package org.scribe.builder.api; + +import org.scribe.model.*; + +public class DropBoxApi extends DefaultApi10a +{ + @Override + public String getAccessTokenEndpoint() + { + return "https://api.dropbox.com/1/oauth/access_token"; + } + + @Override + public String getAuthorizationUrl(Token requestToken) + { + return "https://www.dropbox.com/1/oauth/authorize?oauth_token="+requestToken.getToken(); + } + + @Override + public String getRequestTokenEndpoint() + { + return "https://api.dropbox.com/1/oauth/request_token"; + } + +} \ No newline at end of file diff --git a/src/main/resources/scribe-java-project/src/main/java/org/scribe/builder/api/EvernoteApi.java b/src/main/resources/scribe-java-project/src/main/java/org/scribe/builder/api/EvernoteApi.java new file mode 100644 index 0000000..007f48b --- /dev/null +++ b/src/main/resources/scribe-java-project/src/main/java/org/scribe/builder/api/EvernoteApi.java @@ -0,0 +1,49 @@ +package org.scribe.builder.api; + +import org.scribe.model.Token; + +public class EvernoteApi extends DefaultApi10a +{ + private static final String AUTHORIZATION_URL = "https://www.evernote.com/OAuth.action?oauth_token=%s"; + + @Override + public String getRequestTokenEndpoint() + { + return "https://www.evernote.com/oauth"; + } + + @Override + public String getAccessTokenEndpoint() + { + return "https://www.evernote.com/oauth"; + } + + @Override + public String getAuthorizationUrl(Token requestToken) + { + return String.format(AUTHORIZATION_URL, requestToken.getToken()); + } + + public static class Sandbox extends EvernoteApi + { + private static final String SANDBOX_URL = "https://sandbox.evernote.com"; + + @Override + public String getRequestTokenEndpoint() + { + return SANDBOX_URL + "/oauth"; + } + + @Override + public String getAccessTokenEndpoint() + { + return SANDBOX_URL + "/oauth"; + } + + @Override + public String getAuthorizationUrl(Token requestToken) + { + return String.format(SANDBOX_URL + "/OAuth.action?oauth_token=%s", requestToken.getToken()); + } + } +} diff --git a/src/main/resources/scribe-java-project/src/main/java/org/scribe/builder/api/FacebookApi.java b/src/main/resources/scribe-java-project/src/main/java/org/scribe/builder/api/FacebookApi.java new file mode 100644 index 0000000..996a651 --- /dev/null +++ b/src/main/resources/scribe-java-project/src/main/java/org/scribe/builder/api/FacebookApi.java @@ -0,0 +1,33 @@ +package org.scribe.builder.api; + +import org.scribe.model.*; + +import org.scribe.utils.*; + +public class FacebookApi extends DefaultApi20 +{ + private static final String AUTHORIZE_URL = "https://www.facebook.com/dialog/oauth?client_id=%s&redirect_uri=%s"; + private static final String SCOPED_AUTHORIZE_URL = AUTHORIZE_URL + "&scope=%s"; + + @Override + public String getAccessTokenEndpoint() + { + return "https://graph.facebook.com/oauth/access_token"; + } + + @Override + public String getAuthorizationUrl(OAuthConfig config) + { + Preconditions.checkValidUrl(config.getCallback(), "Must provide a valid url as callback. Facebook does not support OOB"); + + // Append scope if present + if(config.hasScope()) + { + return String.format(SCOPED_AUTHORIZE_URL, config.getApiKey(), OAuthEncoder.encode(config.getCallback()), OAuthEncoder.encode(config.getScope())); + } + else + { + return String.format(AUTHORIZE_URL, config.getApiKey(), OAuthEncoder.encode(config.getCallback())); + } + } +} diff --git a/src/main/resources/scribe-java-project/src/main/java/org/scribe/builder/api/FlickrApi.java b/src/main/resources/scribe-java-project/src/main/java/org/scribe/builder/api/FlickrApi.java new file mode 100644 index 0000000..a630436 --- /dev/null +++ b/src/main/resources/scribe-java-project/src/main/java/org/scribe/builder/api/FlickrApi.java @@ -0,0 +1,40 @@ +package org.scribe.builder.api; + +import org.scribe.model.*; + +/** + * OAuth API for Flickr. + * + * @author Darren Greaves + * @see Flickr API + */ +public class FlickrApi extends DefaultApi10a +{ + + /** + * {@inheritDoc} + */ + @Override + public String getAccessTokenEndpoint() + { + return "http://www.flickr.com/services/oauth/access_token"; + } + + /** + * {@inheritDoc} + */ + @Override + public String getAuthorizationUrl(Token requestToken) + { + return "http://www.flickr.com/services/oauth/authorize?oauth_token=" + requestToken.getToken(); + } + + /** + * {@inheritDoc} + */ + @Override + public String getRequestTokenEndpoint() + { + return "http://www.flickr.com/services/oauth/request_token"; + } +} diff --git a/src/main/resources/scribe-java-project/src/main/java/org/scribe/builder/api/Foursquare2Api.java b/src/main/resources/scribe-java-project/src/main/java/org/scribe/builder/api/Foursquare2Api.java new file mode 100644 index 0000000..d11def9 --- /dev/null +++ b/src/main/resources/scribe-java-project/src/main/java/org/scribe/builder/api/Foursquare2Api.java @@ -0,0 +1,29 @@ +package org.scribe.builder.api; + +import org.scribe.extractors.*; +import org.scribe.model.*; +import org.scribe.utils.*; + +public class Foursquare2Api extends DefaultApi20 +{ + private static final String AUTHORIZATION_URL = "https://foursquare.com/oauth2/authenticate?client_id=%s&response_type=code&redirect_uri=%s"; + + @Override + public String getAccessTokenEndpoint() + { + return "https://foursquare.com/oauth2/access_token?grant_type=authorization_code"; + } + + @Override + public String getAuthorizationUrl(OAuthConfig config) + { + Preconditions.checkValidUrl(config.getCallback(), "Must provide a valid url as callback. Foursquare2 does not support OOB"); + return String.format(AUTHORIZATION_URL, config.getApiKey(), OAuthEncoder.encode(config.getCallback())); + } + + @Override + public AccessTokenExtractor getAccessTokenExtractor() + { + return new JsonTokenExtractor(); + } +} diff --git a/src/main/resources/scribe-java-project/src/main/java/org/scribe/builder/api/FoursquareApi.java b/src/main/resources/scribe-java-project/src/main/java/org/scribe/builder/api/FoursquareApi.java new file mode 100644 index 0000000..060a76b --- /dev/null +++ b/src/main/resources/scribe-java-project/src/main/java/org/scribe/builder/api/FoursquareApi.java @@ -0,0 +1,26 @@ +package org.scribe.builder.api; + +import org.scribe.model.Token; + +public class FoursquareApi extends DefaultApi10a +{ + private static final String AUTHORIZATION_URL = "http://foursquare.com/oauth/authorize?oauth_token=%s"; + + @Override + public String getAccessTokenEndpoint() + { + return "http://foursquare.com/oauth/access_token"; + } + + @Override + public String getRequestTokenEndpoint() + { + return "http://foursquare.com/oauth/request_token"; + } + + @Override + public String getAuthorizationUrl(Token requestToken) + { + return String.format(AUTHORIZATION_URL, requestToken.getToken()); + } +} diff --git a/src/main/resources/scribe-java-project/src/main/java/org/scribe/builder/api/FreelancerApi.java b/src/main/resources/scribe-java-project/src/main/java/org/scribe/builder/api/FreelancerApi.java new file mode 100644 index 0000000..482e66f --- /dev/null +++ b/src/main/resources/scribe-java-project/src/main/java/org/scribe/builder/api/FreelancerApi.java @@ -0,0 +1,61 @@ +package org.scribe.builder.api; + +import org.scribe.model.*; + +public class FreelancerApi extends DefaultApi10a +{ + private static final String AUTHORIZATION_URL = "http://www.freelancer.com/users/api-token/auth.php?oauth_token=%s"; + + @Override + public String getAccessTokenEndpoint() + { + return "http://api.freelancer.com/RequestAccessToken/requestAccessToken.xml?"; + } + + @Override + public String getRequestTokenEndpoint() + { + return "http://api.freelancer.com/RequestRequestToken/requestRequestToken.xml"; + } + + @Override + public Verb getAccessTokenVerb() + { + return Verb.GET; + } + + @Override + public Verb getRequestTokenVerb() + { + return Verb.GET; + } + + @Override + public String getAuthorizationUrl(Token requestToken) + { + return String.format(AUTHORIZATION_URL, requestToken.getToken()); + } + + public static class Sandbox extends FreelancerApi + { + private static final String SANDBOX_AUTHORIZATION_URL = "http://www.sandbox.freelancer.com/users/api-token/auth.php"; + + @Override + public String getRequestTokenEndpoint() + { + return "http://api.sandbox.freelancer.com/RequestRequestToken/requestRequestToken.xml"; + } + + @Override + public String getAccessTokenEndpoint() + { + return "http://api.sandbox.freelancer.com/RequestAccessToken/requestAccessToken.xml?"; + } + + @Override + public String getAuthorizationUrl(Token requestToken) + { + return String.format(SANDBOX_AUTHORIZATION_URL + "?oauth_token=%s", requestToken.getToken()); + } + } +} diff --git a/src/main/resources/scribe-java-project/src/main/java/org/scribe/builder/api/GetGlueApi.java b/src/main/resources/scribe-java-project/src/main/java/org/scribe/builder/api/GetGlueApi.java new file mode 100644 index 0000000..3a7560f --- /dev/null +++ b/src/main/resources/scribe-java-project/src/main/java/org/scribe/builder/api/GetGlueApi.java @@ -0,0 +1,29 @@ +package org.scribe.builder.api; + +import org.scribe.model.Token; + +public class GetGlueApi extends DefaultApi10a +{ + private static final String AUTHORIZE_URL = "http://getglue.com/oauth/authorize?oauth_token=%s"; + private static final String REQUEST_TOKEN_RESOURCE = "https://api.getglue.com/oauth/request_token"; + private static final String ACCESS_TOKEN_RESOURCE = "https://api.getglue.com/oauth/access_token"; + + @Override + public String getAccessTokenEndpoint() + { + return ACCESS_TOKEN_RESOURCE; + } + + @Override + public String getRequestTokenEndpoint() + { + return REQUEST_TOKEN_RESOURCE; + } + + @Override + public String getAuthorizationUrl(Token requestToken) + { + return String.format(AUTHORIZE_URL, requestToken.getToken()); + } + +} diff --git a/src/main/resources/scribe-java-project/src/main/java/org/scribe/builder/api/GoogleApi.java b/src/main/resources/scribe-java-project/src/main/java/org/scribe/builder/api/GoogleApi.java new file mode 100644 index 0000000..9c86e5e --- /dev/null +++ b/src/main/resources/scribe-java-project/src/main/java/org/scribe/builder/api/GoogleApi.java @@ -0,0 +1,38 @@ +package org.scribe.builder.api; + +import org.scribe.model.*; + +public class GoogleApi extends DefaultApi10a +{ + private static final String AUTHORIZATION_URL = "https://www.google.com/accounts/OAuthAuthorizeToken?oauth_token=%s"; + + @Override + public String getAccessTokenEndpoint() + { + return "https://www.google.com/accounts/OAuthGetAccessToken"; + } + + @Override + public String getRequestTokenEndpoint() + { + return "https://www.google.com/accounts/OAuthGetRequestToken"; + } + + @Override + public Verb getAccessTokenVerb() + { + return Verb.GET; + } + + @Override + public Verb getRequestTokenVerb() + { + return Verb.GET; + } + + @Override + public String getAuthorizationUrl(Token requestToken) + { + return String.format(AUTHORIZATION_URL, requestToken.getToken()); + } +} diff --git a/src/main/resources/scribe-java-project/src/main/java/org/scribe/builder/api/ImgUrApi.java b/src/main/resources/scribe-java-project/src/main/java/org/scribe/builder/api/ImgUrApi.java new file mode 100644 index 0000000..06dd691 --- /dev/null +++ b/src/main/resources/scribe-java-project/src/main/java/org/scribe/builder/api/ImgUrApi.java @@ -0,0 +1,32 @@ +package org.scribe.builder.api; + +import org.scribe.model.*; + +/** + * OAuth API for ImgUr + * + * @author David Wursteisen + * @see ImgUr API + */ +public class ImgUrApi extends DefaultApi10a +{ + + @Override + public String getRequestTokenEndpoint() + { + return "https://api.imgur.com/oauth/request_token"; + } + + @Override + public String getAccessTokenEndpoint() + { + return "https://api.imgur.com/oauth/access_token"; + } + + @Override + public String getAuthorizationUrl(Token requestToken) + { + return String.format("https://api.imgur.com/oauth/authorize?oauth_token=%s", requestToken.getToken()); + } +} + diff --git a/src/main/resources/scribe-java-project/src/main/java/org/scribe/builder/api/KaixinApi.java b/src/main/resources/scribe-java-project/src/main/java/org/scribe/builder/api/KaixinApi.java new file mode 100644 index 0000000..5b0e0d5 --- /dev/null +++ b/src/main/resources/scribe-java-project/src/main/java/org/scribe/builder/api/KaixinApi.java @@ -0,0 +1,40 @@ +package org.scribe.builder.api; + +import org.scribe.model.*; + +public class KaixinApi extends DefaultApi10a +{ + private static final String REQUEST_TOKEN_URL = "http://api.kaixin001.com/oauth/request_token"; + private static final String ACCESS_TOKEN_URL = "http://api.kaixin001.com/oauth/access_token"; + private static final String AUTHORIZE_URL = "http://api.kaixin001.com/oauth/authorize?oauth_token=%s"; + + @Override + public String getRequestTokenEndpoint() + { + return REQUEST_TOKEN_URL; + } + + @Override + public String getAccessTokenEndpoint() + { + return ACCESS_TOKEN_URL; + } + + @Override + public String getAuthorizationUrl(Token requestToken) + { + return String.format(AUTHORIZE_URL, requestToken.getToken()); + } + + @Override + public Verb getRequestTokenVerb() + { + return Verb.GET; + } + + @Override + public Verb getAccessTokenVerb() + { + return Verb.GET; + } +} diff --git a/src/main/resources/scribe-java-project/src/main/java/org/scribe/builder/api/KaixinApi20.java b/src/main/resources/scribe-java-project/src/main/java/org/scribe/builder/api/KaixinApi20.java new file mode 100644 index 0000000..9e27bcb --- /dev/null +++ b/src/main/resources/scribe-java-project/src/main/java/org/scribe/builder/api/KaixinApi20.java @@ -0,0 +1,41 @@ +package org.scribe.builder.api; + +import org.scribe.extractors.*; +import org.scribe.model.*; +import org.scribe.utils.*; + +/** + * Kaixin(http://www.kaixin001.com/) open platform api based on OAuth 2.0. + */ +public class KaixinApi20 extends DefaultApi20 +{ + + private static final String AUTHORIZE_URL = "http://api.kaixin001.com/oauth2/authorize?client_id=%s&redirect_uri=%s&response_type=code"; + private static final String SCOPED_AUTHORIZE_URL = AUTHORIZE_URL + "&scope=%s"; + + @Override + public AccessTokenExtractor getAccessTokenExtractor() + { + return new JsonTokenExtractor(); + } + + @Override + public String getAccessTokenEndpoint() + { + return "https://api.kaixin001.com/oauth2/access_token?grant_type=authorization_code"; + } + + @Override + public String getAuthorizationUrl(OAuthConfig config) + { + // Append scope if present + if (config.hasScope()) + { + return String.format(SCOPED_AUTHORIZE_URL, config.getApiKey(), OAuthEncoder.encode(config.getCallback()), OAuthEncoder.encode(config.getScope())); + } + else + { + return String.format(AUTHORIZE_URL, config.getApiKey(), OAuthEncoder.encode(config.getCallback())); + } + } +} diff --git a/src/main/resources/scribe-java-project/src/main/java/org/scribe/builder/api/LinkedInApi.java b/src/main/resources/scribe-java-project/src/main/java/org/scribe/builder/api/LinkedInApi.java new file mode 100644 index 0000000..ee6becd --- /dev/null +++ b/src/main/resources/scribe-java-project/src/main/java/org/scribe/builder/api/LinkedInApi.java @@ -0,0 +1,57 @@ +package org.scribe.builder.api; + +import org.scribe.model.*; +import java.util.*; + +public class LinkedInApi extends DefaultApi10a +{ + private static final String AUTHORIZE_URL = "https://api.linkedin.com/uas/oauth/authenticate?oauth_token=%s"; + private static final String REQUEST_TOKEN_URL = "https://api.linkedin.com/uas/oauth/requestToken"; + + private final Set scopes; + + public LinkedInApi() + { + scopes = Collections.emptySet(); + } + + public LinkedInApi(Set scopes) + { + this.scopes = Collections.unmodifiableSet(scopes); + } + + @Override + public String getAccessTokenEndpoint() + { + return "https://api.linkedin.com/uas/oauth/accessToken"; + } + + @Override + public String getRequestTokenEndpoint() + { + return scopes.isEmpty() ? REQUEST_TOKEN_URL : REQUEST_TOKEN_URL + "?scope=" + scopesAsString(); + } + + private String scopesAsString() + { + StringBuilder builder = new StringBuilder(); + for(String scope : scopes) + { + builder.append("+" + scope); + } + return builder.substring(1); + } + + @Override + public String getAuthorizationUrl(Token requestToken) + { + return String.format(AUTHORIZE_URL, requestToken.getToken()); + } + + public static LinkedInApi withScopes(String... scopes) + { + Set scopeSet = new HashSet(Arrays.asList(scopes)); + return new LinkedInApi(scopeSet); + } + +} diff --git a/src/main/resources/scribe-java-project/src/main/java/org/scribe/builder/api/LiveApi.java b/src/main/resources/scribe-java-project/src/main/java/org/scribe/builder/api/LiveApi.java new file mode 100644 index 0000000..18140f6 --- /dev/null +++ b/src/main/resources/scribe-java-project/src/main/java/org/scribe/builder/api/LiveApi.java @@ -0,0 +1,40 @@ +package org.scribe.builder.api; + +import org.scribe.extractors.*; +import org.scribe.model.*; +import org.scribe.utils.*; + +public class LiveApi extends DefaultApi20 +{ + + private static final String AUTHORIZE_URL = "https://oauth.live.com/authorize?client_id=%s&redirect_uri=%s&response_type=code"; + private static final String SCOPED_AUTHORIZE_URL = AUTHORIZE_URL + "&scope=%s"; + + @Override + public String getAccessTokenEndpoint() + { + return "https://oauth.live.com/token?grant_type=authorization_code"; + } + + @Override + public String getAuthorizationUrl(OAuthConfig config) + { + Preconditions.checkValidUrl(config.getCallback(), "Must provide a valid url as callback. Live does not support OOB"); + + // Append scope if present + if (config.hasScope()) + { + return String.format(SCOPED_AUTHORIZE_URL, config.getApiKey(), OAuthEncoder.encode(config.getCallback()), OAuthEncoder.encode(config.getScope())); + } + else + { + return String.format(AUTHORIZE_URL, config.getApiKey(), OAuthEncoder.encode(config.getCallback())); + } + } + + @Override + public AccessTokenExtractor getAccessTokenExtractor() + { + return new JsonTokenExtractor(); + } +} \ No newline at end of file diff --git a/src/main/resources/scribe-java-project/src/main/java/org/scribe/builder/api/LoveFilmApi.java b/src/main/resources/scribe-java-project/src/main/java/org/scribe/builder/api/LoveFilmApi.java new file mode 100644 index 0000000..81a5bb8 --- /dev/null +++ b/src/main/resources/scribe-java-project/src/main/java/org/scribe/builder/api/LoveFilmApi.java @@ -0,0 +1,28 @@ +package org.scribe.builder.api; + +import org.scribe.model.Token; + +public class LoveFilmApi extends DefaultApi10a +{ + private static final String REQUEST_TOKEN_URL = "http://openapi.lovefilm.com/oauth/request_token"; + private static final String ACCESS_TOKEN_URL = "http://openapi.lovefilm.com/oauth/access_token"; + private static final String AUTHORIZE_URL = "https://www.lovefilm.com/activate?oauth_token=%s"; + + @Override + public String getRequestTokenEndpoint() + { + return REQUEST_TOKEN_URL; + } + + @Override + public String getAccessTokenEndpoint() + { + return ACCESS_TOKEN_URL; + } + + @Override + public String getAuthorizationUrl(Token requestToken) + { + return String.format(AUTHORIZE_URL, requestToken.getToken()); + } +} diff --git a/src/main/resources/scribe-java-project/src/main/java/org/scribe/builder/api/MeetupApi.java b/src/main/resources/scribe-java-project/src/main/java/org/scribe/builder/api/MeetupApi.java new file mode 100644 index 0000000..8f63e39 --- /dev/null +++ b/src/main/resources/scribe-java-project/src/main/java/org/scribe/builder/api/MeetupApi.java @@ -0,0 +1,30 @@ +package org.scribe.builder.api; + +import org.scribe.model.Token; + +/** + * OAuth access to the Meetup.com API. + * For more information visit http://www.meetup.com/api + */ +public class MeetupApi extends DefaultApi10a +{ + private static final String AUTHORIZE_URL = "http://www.meetup.com/authenticate?oauth_token=%s"; + + @Override + public String getRequestTokenEndpoint() + { + return "http://api.meetup.com/oauth/request/"; + } + + @Override + public String getAccessTokenEndpoint() + { + return "http://api.meetup.com/oauth/access/"; + } + + @Override + public String getAuthorizationUrl(Token requestToken) + { + return String.format(AUTHORIZE_URL, requestToken.getToken()); + } +} diff --git a/src/main/resources/scribe-java-project/src/main/java/org/scribe/builder/api/MendeleyApi.java b/src/main/resources/scribe-java-project/src/main/java/org/scribe/builder/api/MendeleyApi.java new file mode 100644 index 0000000..c6e0ece --- /dev/null +++ b/src/main/resources/scribe-java-project/src/main/java/org/scribe/builder/api/MendeleyApi.java @@ -0,0 +1,43 @@ +package org.scribe.builder.api; + +import org.scribe.model.*; + +/** + * @author Arieh "Vainolo" Bibliowicz + * @see http://apidocs.mendeley.com/home/authentication + */ +public class MendeleyApi extends DefaultApi10a +{ + + private static final String AUTHORIZATION_URL = "http://api.mendeley.com/oauth/authorize?oauth_token=%s"; + + @Override + public String getRequestTokenEndpoint() + { + return "http://api.mendeley.com/oauth/request_token/"; + } + + @Override + public String getAccessTokenEndpoint() + { + return "http://api.mendeley.com/oauth/access_token/"; + } + + @Override + public String getAuthorizationUrl(Token requestToken) + { + return String.format(AUTHORIZATION_URL, requestToken.getToken()); + } + + @Override + public Verb getAccessTokenVerb() + { + return Verb.GET; + } + + @Override + public Verb getRequestTokenVerb() + { + return Verb.GET; + } +} diff --git a/src/main/resources/scribe-java-project/src/main/java/org/scribe/builder/api/MisoApi.java b/src/main/resources/scribe-java-project/src/main/java/org/scribe/builder/api/MisoApi.java new file mode 100644 index 0000000..a6d88d3 --- /dev/null +++ b/src/main/resources/scribe-java-project/src/main/java/org/scribe/builder/api/MisoApi.java @@ -0,0 +1,29 @@ +package org.scribe.builder.api; + +import org.scribe.model.Token; + +public class MisoApi extends DefaultApi10a +{ + private static final String AUTHORIZE_URL = "http://gomiso.com/oauth/authorize?oauth_token=%s"; + private static final String REQUEST_TOKEN_RESOURCE = "http://gomiso.com/oauth/request_token"; + private static final String ACCESS_TOKEN_RESOURCE = "http://gomiso.com/oauth/access_token"; + + @Override + public String getAccessTokenEndpoint() + { + return ACCESS_TOKEN_RESOURCE; + } + + @Override + public String getRequestTokenEndpoint() + { + return REQUEST_TOKEN_RESOURCE; + } + + @Override + public String getAuthorizationUrl(Token requestToken) + { + return String.format(AUTHORIZE_URL, requestToken.getToken()); + } + +} diff --git a/src/main/resources/scribe-java-project/src/main/java/org/scribe/builder/api/NetProspexApi.java b/src/main/resources/scribe-java-project/src/main/java/org/scribe/builder/api/NetProspexApi.java new file mode 100644 index 0000000..8257de7 --- /dev/null +++ b/src/main/resources/scribe-java-project/src/main/java/org/scribe/builder/api/NetProspexApi.java @@ -0,0 +1,28 @@ +package org.scribe.builder.api; + +import org.scribe.model.Token; + +public class NetProspexApi extends DefaultApi10a +{ + private static final String REQUEST_TOKEN_URL = "https://api.netprospex.com/1.0/oauth/request-token"; + private static final String ACCESS_TOKEN_URL = "https://api.netprospex.com/1.0/oauth/access-token"; + private static final String AUTHORIZE_URL = "https://api.netprospex.com/1.0/oauth/authorize?oauth_token=%s"; + + @Override + public String getRequestTokenEndpoint() + { + return REQUEST_TOKEN_URL; + } + + @Override + public String getAccessTokenEndpoint() + { + return ACCESS_TOKEN_URL; + } + + @Override + public String getAuthorizationUrl(Token requestToken) + { + return String.format(AUTHORIZE_URL, requestToken.getToken()); + } +} diff --git a/src/main/resources/scribe-java-project/src/main/java/org/scribe/builder/api/NeteaseWeibooApi.java b/src/main/resources/scribe-java-project/src/main/java/org/scribe/builder/api/NeteaseWeibooApi.java new file mode 100644 index 0000000..fae38ac --- /dev/null +++ b/src/main/resources/scribe-java-project/src/main/java/org/scribe/builder/api/NeteaseWeibooApi.java @@ -0,0 +1,47 @@ +package org.scribe.builder.api; + +import org.scribe.model.*; + +public class NeteaseWeibooApi extends DefaultApi10a +{ + private static final String REQUEST_TOKEN_URL = "http://api.t.163.com/oauth/request_token"; + private static final String ACCESS_TOKEN_URL = "http://api.t.163.com/oauth/access_token"; + private static final String AUTHORIZE_URL = "http://api.t.163.com/oauth/authorize?oauth_token=%s"; + private static final String AUTHENTICATE_URL = "http://api.t.163.com/oauth/authenticate?oauth_token=%s"; + + @Override + public String getRequestTokenEndpoint() + { + return REQUEST_TOKEN_URL; + } + + @Override + public String getAccessTokenEndpoint() + { + return ACCESS_TOKEN_URL; + } + + @Override + /** + * this method will ignore your callback + * if you're creating a desktop client please choose this url + * else your can call getAuthenticateUrl + * + * via http://open.t.163.com/wiki/index.php?title=%E8%AF%B7%E6%B1%82%E7%94%A8%E6%88%B7%E6%8E%88%E6%9D%83Token(oauth/authorize) + */ + public String getAuthorizationUrl(Token requestToken) + { + return String.format(AUTHORIZE_URL, requestToken.getToken()); + } + + /** + * this method is for web client with callback url + * if you're creating a desktop client please call getAuthorizationUrl + * + * via http://open.t.163.com/wiki/index.php?title=%E8%AF%B7%E6%B1%82%E7%94%A8%E6%88%B7%E6%8E%88%E6%9D%83Token(oauth/authenticate) + */ + public String getAuthenticateUrl(Token requestToken) + { + return String.format(AUTHENTICATE_URL, requestToken.getToken()); + } +} diff --git a/src/main/resources/scribe-java-project/src/main/java/org/scribe/builder/api/PlurkApi.java b/src/main/resources/scribe-java-project/src/main/java/org/scribe/builder/api/PlurkApi.java new file mode 100644 index 0000000..22b1ddb --- /dev/null +++ b/src/main/resources/scribe-java-project/src/main/java/org/scribe/builder/api/PlurkApi.java @@ -0,0 +1,39 @@ +package org.scribe.builder.api; + +import org.scribe.model.Token; + +public class PlurkApi extends DefaultApi10a +{ + private static final String REQUEST_TOKEN_URL = "http://www.plurk.com/OAuth/request_token"; + private static final String AUTHORIZATION_URL = "http://www.plurk.com/OAuth/authorize?oauth_token=%s"; + private static final String ACCESS_TOKEN_URL = "http://www.plurk.com/OAuth/access_token"; + + @Override + public String getRequestTokenEndpoint() + { + return REQUEST_TOKEN_URL; + } + + @Override + public String getAuthorizationUrl(Token requestToken) + { + return String.format(AUTHORIZATION_URL, requestToken.getToken()); + } + + @Override + public String getAccessTokenEndpoint() + { + return ACCESS_TOKEN_URL; + } + + public static class Mobile extends PlurkApi + { + private static final String AUTHORIZATION_URL = "http://www.plurk.com/m/authorize?oauth_token=%s"; + + @Override + public String getAuthorizationUrl(Token requestToken) + { + return String.format(AUTHORIZATION_URL, requestToken.getToken()); + } + } +} diff --git a/src/main/resources/scribe-java-project/src/main/java/org/scribe/builder/api/Px500Api.java b/src/main/resources/scribe-java-project/src/main/java/org/scribe/builder/api/Px500Api.java new file mode 100644 index 0000000..f7f3b0e --- /dev/null +++ b/src/main/resources/scribe-java-project/src/main/java/org/scribe/builder/api/Px500Api.java @@ -0,0 +1,26 @@ +package org.scribe.builder.api; + +import org.scribe.model.*; + +public class Px500Api extends DefaultApi10a +{ + private static final String AUTHORIZATION_URL = "https://api.500px.com/v1/oauth/authorize?oauth_token=%s"; + + @Override + public String getAccessTokenEndpoint() + { + return "https://api.500px.com/v1/oauth/access_token"; + } + + @Override + public String getRequestTokenEndpoint() + { + return "https://api.500px.com/v1/oauth/request_token"; + } + + @Override + public String getAuthorizationUrl(Token requestToken) + { + return String.format(AUTHORIZATION_URL, requestToken.getToken()); + } +} \ No newline at end of file diff --git a/src/main/resources/scribe-java-project/src/main/java/org/scribe/builder/api/QWeiboApi.java b/src/main/resources/scribe-java-project/src/main/java/org/scribe/builder/api/QWeiboApi.java new file mode 100644 index 0000000..e16f288 --- /dev/null +++ b/src/main/resources/scribe-java-project/src/main/java/org/scribe/builder/api/QWeiboApi.java @@ -0,0 +1,28 @@ +package org.scribe.builder.api; + +import org.scribe.model.*; + +public class QWeiboApi extends DefaultApi10a +{ + private static final String REQUEST_TOKEN_URL = "https://open.t.qq.com/cgi-bin/request_token"; + private static final String ACCESS_TOKEN_URL = "https://open.t.qq.com/cgi-bin/access_token"; + private static final String AUTHORIZE_URL = "https://open.t.qq.com/cgi-bin/authorize?oauth_token=%s"; + + @Override + public String getRequestTokenEndpoint() + { + return REQUEST_TOKEN_URL; + } + + @Override + public String getAccessTokenEndpoint() + { + return ACCESS_TOKEN_URL; + } + + @Override + public String getAuthorizationUrl(Token requestToken) + { + return String.format(AUTHORIZE_URL, requestToken.getToken()); + } +} diff --git a/src/main/resources/scribe-java-project/src/main/java/org/scribe/builder/api/RenrenApi.java b/src/main/resources/scribe-java-project/src/main/java/org/scribe/builder/api/RenrenApi.java new file mode 100644 index 0000000..b31337b --- /dev/null +++ b/src/main/resources/scribe-java-project/src/main/java/org/scribe/builder/api/RenrenApi.java @@ -0,0 +1,40 @@ +package org.scribe.builder.api; + +import org.scribe.extractors.*; +import org.scribe.model.*; +import org.scribe.utils.*; + +/** + * Renren(http://www.renren.com/) OAuth 2.0 based api. + */ +public class RenrenApi extends DefaultApi20 +{ + private static final String AUTHORIZE_URL = "https://graph.renren.com/oauth/authorize?client_id=%s&redirect_uri=%s&response_type=code"; + private static final String SCOPED_AUTHORIZE_URL = AUTHORIZE_URL + "&scope=%s"; + + @Override + public AccessTokenExtractor getAccessTokenExtractor() + { + return new JsonTokenExtractor(); + } + + @Override + public String getAccessTokenEndpoint() + { + return "https://graph.renren.com/oauth/token?grant_type=authorization_code"; + } + + @Override + public String getAuthorizationUrl(OAuthConfig config) + { + // Append scope if present + if (config.hasScope()) + { + return String.format(SCOPED_AUTHORIZE_URL, config.getApiKey(), OAuthEncoder.encode(config.getCallback()), OAuthEncoder.encode(config.getScope())); + } + else + { + return String.format(AUTHORIZE_URL, config.getApiKey(), OAuthEncoder.encode(config.getCallback())); + } + } +} diff --git a/src/main/resources/scribe-java-project/src/main/java/org/scribe/builder/api/SapoApi.java b/src/main/resources/scribe-java-project/src/main/java/org/scribe/builder/api/SapoApi.java new file mode 100644 index 0000000..9771daf --- /dev/null +++ b/src/main/resources/scribe-java-project/src/main/java/org/scribe/builder/api/SapoApi.java @@ -0,0 +1,40 @@ +package org.scribe.builder.api; + +import org.scribe.model.*; + +public class SapoApi extends DefaultApi10a +{ + private static final String AUTHORIZE_URL = "https://id.sapo.pt/oauth/authorize?oauth_token=%s"; + private static final String ACCESS_URL = "https://id.sapo.pt/oauth/access_token"; + private static final String REQUEST_URL = "https://id.sapo.pt/oauth/request_token"; + + @Override + public String getAccessTokenEndpoint() + { + return ACCESS_URL; + } + + @Override + public String getRequestTokenEndpoint() + { + return REQUEST_URL; + } + + @Override + public String getAuthorizationUrl(Token requestToken) + { + return String.format(AUTHORIZE_URL, requestToken.getToken()); + } + + @Override + public Verb getRequestTokenVerb() + { + return Verb.GET; + } + + @Override + public Verb getAccessTokenVerb() + { + return Verb.GET; + } +} \ No newline at end of file diff --git a/src/main/resources/scribe-java-project/src/main/java/org/scribe/builder/api/SimpleGeoApi.java b/src/main/resources/scribe-java-project/src/main/java/org/scribe/builder/api/SimpleGeoApi.java new file mode 100644 index 0000000..3e19df7 --- /dev/null +++ b/src/main/resources/scribe-java-project/src/main/java/org/scribe/builder/api/SimpleGeoApi.java @@ -0,0 +1,29 @@ +package org.scribe.builder.api; + +import org.scribe.model.Token; + +/** + * @author: Pablo Fernandez + */ +public class SimpleGeoApi extends DefaultApi10a +{ + private static final String ENDPOINT = "these are not used since SimpleGeo uses 2 legged OAuth"; + + @Override + public String getRequestTokenEndpoint() + { + return ENDPOINT; + } + + @Override + public String getAccessTokenEndpoint() + { + return ENDPOINT; + } + + @Override + public String getAuthorizationUrl(Token requestToken) + { + return ENDPOINT; + } +} diff --git a/src/main/resources/scribe-java-project/src/main/java/org/scribe/builder/api/SinaWeiboApi.java b/src/main/resources/scribe-java-project/src/main/java/org/scribe/builder/api/SinaWeiboApi.java new file mode 100644 index 0000000..14951d3 --- /dev/null +++ b/src/main/resources/scribe-java-project/src/main/java/org/scribe/builder/api/SinaWeiboApi.java @@ -0,0 +1,28 @@ +package org.scribe.builder.api; + +import org.scribe.model.*; + +public class SinaWeiboApi extends DefaultApi10a +{ + private static final String REQUEST_TOKEN_URL = "http://api.t.sina.com.cn/oauth/request_token"; + private static final String ACCESS_TOKEN_URL = "http://api.t.sina.com.cn/oauth/access_token"; + private static final String AUTHORIZE_URL = "http://api.t.sina.com.cn/oauth/authorize?oauth_token=%s"; + + @Override + public String getRequestTokenEndpoint() + { + return REQUEST_TOKEN_URL; + } + + @Override + public String getAccessTokenEndpoint() + { + return ACCESS_TOKEN_URL; + } + + @Override + public String getAuthorizationUrl(Token requestToken) + { + return String.format(AUTHORIZE_URL, requestToken.getToken()); + } +} diff --git a/src/main/resources/scribe-java-project/src/main/java/org/scribe/builder/api/SinaWeiboApi20.java b/src/main/resources/scribe-java-project/src/main/java/org/scribe/builder/api/SinaWeiboApi20.java new file mode 100644 index 0000000..e0744c4 --- /dev/null +++ b/src/main/resources/scribe-java-project/src/main/java/org/scribe/builder/api/SinaWeiboApi20.java @@ -0,0 +1,46 @@ +package org.scribe.builder.api; + +import org.scribe.extractors.*; +import org.scribe.model.*; +import org.scribe.utils.*; + +/** + * SinaWeibo OAuth 2.0 api. + */ +public class SinaWeiboApi20 extends DefaultApi20 +{ + private static final String AUTHORIZE_URL = "https://api.weibo.com/oauth2/authorize?client_id=%s&redirect_uri=%s&response_type=code"; + private static final String SCOPED_AUTHORIZE_URL = AUTHORIZE_URL + "&scope=%s"; + + @Override + public Verb getAccessTokenVerb() + { + return Verb.POST; + } + + @Override + public AccessTokenExtractor getAccessTokenExtractor() + { + return new JsonTokenExtractor(); + } + + @Override + public String getAccessTokenEndpoint() + { + return "https://api.weibo.com/oauth2/access_token?grant_type=authorization_code"; + } + + @Override + public String getAuthorizationUrl(OAuthConfig config) + { + // Append scope if present + if (config.hasScope()) + { + return String.format(SCOPED_AUTHORIZE_URL, config.getApiKey(), OAuthEncoder.encode(config.getCallback()), OAuthEncoder.encode(config.getScope())); + } + else + { + return String.format(AUTHORIZE_URL, config.getApiKey(), OAuthEncoder.encode(config.getCallback())); + } + } +} diff --git a/src/main/resources/scribe-java-project/src/main/java/org/scribe/builder/api/SkyrockApi.java b/src/main/resources/scribe-java-project/src/main/java/org/scribe/builder/api/SkyrockApi.java new file mode 100644 index 0000000..b0e76a3 --- /dev/null +++ b/src/main/resources/scribe-java-project/src/main/java/org/scribe/builder/api/SkyrockApi.java @@ -0,0 +1,35 @@ +package org.scribe.builder.api; + +import org.scribe.model.*; + +/** + * OAuth API for Skyrock. + * + * @author Nicolas Quiénot + * @see Skyrock.com API + */ +public class SkyrockApi extends DefaultApi10a +{ + private static final String API_ENDPOINT = "https://api.skyrock.com/v2"; + private static final String REQUEST_TOKEN_RESOURCE = "/oauth/initiate"; + private static final String AUTHORIZE_URL = "/oauth/authorize?oauth_token=%s"; + private static final String ACCESS_TOKEN_RESOURCE = "/oauth/token"; + + @Override + public String getAccessTokenEndpoint() + { + return API_ENDPOINT + ACCESS_TOKEN_RESOURCE; + } + + @Override + public String getRequestTokenEndpoint() + { + return API_ENDPOINT + REQUEST_TOKEN_RESOURCE; + } + + @Override + public String getAuthorizationUrl(Token requestToken) + { + return String.format(API_ENDPOINT + AUTHORIZE_URL, requestToken.getToken()); + } +} diff --git a/src/main/resources/scribe-java-project/src/main/java/org/scribe/builder/api/SohuWeiboApi.java b/src/main/resources/scribe-java-project/src/main/java/org/scribe/builder/api/SohuWeiboApi.java new file mode 100644 index 0000000..1f927b7 --- /dev/null +++ b/src/main/resources/scribe-java-project/src/main/java/org/scribe/builder/api/SohuWeiboApi.java @@ -0,0 +1,28 @@ +package org.scribe.builder.api; + +import org.scribe.model.*; + +public class SohuWeiboApi extends DefaultApi10a +{ + private static final String REQUEST_TOKEN_URL = "http://api.t.sohu.com/oauth/request_token"; + private static final String ACCESS_TOKEN_URL = "http://api.t.sohu.com/oauth/access_token"; + private static final String AUTHORIZE_URL = "http://api.t.sohu.com/oauth/authorize?oauth_token=%s"; + + @Override + public String getRequestTokenEndpoint() + { + return REQUEST_TOKEN_URL; + } + + @Override + public String getAccessTokenEndpoint() + { + return ACCESS_TOKEN_URL; + } + + @Override + public String getAuthorizationUrl(Token requestToken) + { + return String.format(AUTHORIZE_URL, requestToken.getToken()); + } +} diff --git a/src/main/resources/scribe-java-project/src/main/java/org/scribe/builder/api/TrelloApi.java b/src/main/resources/scribe-java-project/src/main/java/org/scribe/builder/api/TrelloApi.java new file mode 100644 index 0000000..9e46730 --- /dev/null +++ b/src/main/resources/scribe-java-project/src/main/java/org/scribe/builder/api/TrelloApi.java @@ -0,0 +1,27 @@ +package org.scribe.builder.api; + +import org.scribe.model.*; + +public class TrelloApi extends DefaultApi10a +{ + private static final String AUTHORIZE_URL = "https://trello.com/1/OAuthAuthorizeToken?oauth_token=%s"; + + @Override + public String getAccessTokenEndpoint() + { + return "https://trello.com/1/OAuthGetAccessToken"; + } + + @Override + public String getRequestTokenEndpoint() + { + return "https://trello.com/1/OAuthGetRequestToken"; + } + + @Override + public String getAuthorizationUrl(Token requestToken) + { + return String.format(AUTHORIZE_URL, requestToken.getToken()); + } + +} diff --git a/src/main/resources/scribe-java-project/src/main/java/org/scribe/builder/api/TumblrApi.java b/src/main/resources/scribe-java-project/src/main/java/org/scribe/builder/api/TumblrApi.java new file mode 100644 index 0000000..ee680ee --- /dev/null +++ b/src/main/resources/scribe-java-project/src/main/java/org/scribe/builder/api/TumblrApi.java @@ -0,0 +1,28 @@ +package org.scribe.builder.api; + +import org.scribe.model.Token; + +public class TumblrApi extends DefaultApi10a +{ + private static final String AUTHORIZE_URL = "https://www.tumblr.com/oauth/authorize?oauth_token=%s"; + private static final String REQUEST_TOKEN_RESOURCE = "http://www.tumblr.com/oauth/request_token"; + private static final String ACCESS_TOKEN_RESOURCE = "http://www.tumblr.com/oauth/access_token"; + + @Override + public String getAccessTokenEndpoint() + { + return ACCESS_TOKEN_RESOURCE; + } + + @Override + public String getRequestTokenEndpoint() + { + return REQUEST_TOKEN_RESOURCE; + } + + @Override + public String getAuthorizationUrl(Token requestToken) + { + return String.format(AUTHORIZE_URL, requestToken.getToken()); + } +} diff --git a/src/main/resources/scribe-java-project/src/main/java/org/scribe/builder/api/TwitterApi.java b/src/main/resources/scribe-java-project/src/main/java/org/scribe/builder/api/TwitterApi.java new file mode 100644 index 0000000..86494c5 --- /dev/null +++ b/src/main/resources/scribe-java-project/src/main/java/org/scribe/builder/api/TwitterApi.java @@ -0,0 +1,42 @@ +package org.scribe.builder.api; + +import org.scribe.model.Token; + +public class TwitterApi extends DefaultApi10a +{ + private static final String AUTHORIZE_URL = "https://api.twitter.com/oauth/authorize?oauth_token=%s"; + private static final String REQUEST_TOKEN_RESOURCE = "api.twitter.com/oauth/request_token"; + private static final String ACCESS_TOKEN_RESOURCE = "api.twitter.com/oauth/access_token"; + + @Override + public String getAccessTokenEndpoint() + { + return "https://" + ACCESS_TOKEN_RESOURCE; + } + + @Override + public String getRequestTokenEndpoint() + { + return "https://" + REQUEST_TOKEN_RESOURCE; + } + + @Override + public String getAuthorizationUrl(Token requestToken) + { + return String.format(AUTHORIZE_URL, requestToken.getToken()); + } + + /** + * Twitter 'friendlier' authorization endpoint for OAuth. + */ + public static class Authenticate extends TwitterApi + { + private static final String AUTHENTICATE_URL = "https://api.twitter.com/oauth/authenticate?oauth_token=%s"; + + @Override + public String getAuthorizationUrl(Token requestToken) + { + return String.format(AUTHENTICATE_URL, requestToken.getToken()); + } + } +} diff --git a/src/main/resources/scribe-java-project/src/main/java/org/scribe/builder/api/UbuntuOneApi.java b/src/main/resources/scribe-java-project/src/main/java/org/scribe/builder/api/UbuntuOneApi.java new file mode 100644 index 0000000..2a72c3a --- /dev/null +++ b/src/main/resources/scribe-java-project/src/main/java/org/scribe/builder/api/UbuntuOneApi.java @@ -0,0 +1,40 @@ +package org.scribe.builder.api; + +import org.scribe.model.Token; +import org.scribe.services.*; + +/** + * @author Julio Gutierrez + * + * Sep 6, 2012 + */ +public class UbuntuOneApi extends DefaultApi10a +{ + + private static final String AUTHORIZATION_URL = "https://one.ubuntu.com/oauth/authorize/?oauth_token=%s"; + + @Override + public String getAccessTokenEndpoint() + { + return "https://one.ubuntu.com/oauth/access/"; + } + + @Override + public String getAuthorizationUrl(Token requestToken) + { + return String.format(AUTHORIZATION_URL, requestToken.getToken()); + } + + @Override + public String getRequestTokenEndpoint() + { + return "https://one.ubuntu.com/oauth/request/"; + } + + @Override + public SignatureService getSignatureService() + { + return new PlaintextSignatureService(); + } + +} diff --git a/src/main/resources/scribe-java-project/src/main/java/org/scribe/builder/api/ViadeoApi.java b/src/main/resources/scribe-java-project/src/main/java/org/scribe/builder/api/ViadeoApi.java new file mode 100644 index 0000000..0f5e77e --- /dev/null +++ b/src/main/resources/scribe-java-project/src/main/java/org/scribe/builder/api/ViadeoApi.java @@ -0,0 +1,42 @@ +package org.scribe.builder.api; + +import org.scribe.extractors.AccessTokenExtractor; +import org.scribe.model.OAuthConfig; +import org.scribe.utils.OAuthEncoder; +import org.scribe.utils.Preconditions; + +import org.scribe.extractors.JsonTokenExtractor; + +public class ViadeoApi extends DefaultApi20 +{ + private static final String AUTHORIZE_URL = "https://secure.viadeo.com/oauth-provider/authorize2?client_id=%s&redirect_uri=%s&response_type=code"; + private static final String SCOPED_AUTHORIZE_URL = AUTHORIZE_URL + "&scope=%s"; + + @Override + public AccessTokenExtractor getAccessTokenExtractor() + { + return new JsonTokenExtractor(); + } + + @Override + public String getAccessTokenEndpoint() + { + return "https://secure.viadeo.com/oauth-provider/access_token2?grant_type=authorization_code"; + } + + @Override + public String getAuthorizationUrl(OAuthConfig config) + { + Preconditions.checkValidUrl(config.getCallback(), "Must provide a valid url as callback. Viadeo does not support OOB"); + + // Append scope if present + if(config.hasScope()) + { + return String.format(SCOPED_AUTHORIZE_URL, config.getApiKey(), OAuthEncoder.encode(config.getCallback()), OAuthEncoder.encode(config.getScope())); + } + else + { + return String.format(AUTHORIZE_URL, config.getApiKey(), OAuthEncoder.encode(config.getCallback())); + } + } +} diff --git a/src/main/resources/scribe-java-project/src/main/java/org/scribe/builder/api/VimeoApi.java b/src/main/resources/scribe-java-project/src/main/java/org/scribe/builder/api/VimeoApi.java new file mode 100644 index 0000000..231895d --- /dev/null +++ b/src/main/resources/scribe-java-project/src/main/java/org/scribe/builder/api/VimeoApi.java @@ -0,0 +1,26 @@ +package org.scribe.builder.api; + +import org.scribe.model.Token; + +public class VimeoApi extends DefaultApi10a +{ + private static final String AUTHORIZATION_URL = "http://vimeo.com/oauth/authorize?oauth_token=%s"; + + @Override + public String getAccessTokenEndpoint() + { + return "http://vimeo.com/oauth/access_token"; + } + + @Override + public String getRequestTokenEndpoint() + { + return "http://vimeo.com/oauth/request_token"; + } + + @Override + public String getAuthorizationUrl(Token requestToken) + { + return String.format(AUTHORIZATION_URL, requestToken.getToken()); + } +} diff --git a/src/main/resources/scribe-java-project/src/main/java/org/scribe/builder/api/VkontakteApi.java b/src/main/resources/scribe-java-project/src/main/java/org/scribe/builder/api/VkontakteApi.java new file mode 100644 index 0000000..e12f395 --- /dev/null +++ b/src/main/resources/scribe-java-project/src/main/java/org/scribe/builder/api/VkontakteApi.java @@ -0,0 +1,41 @@ +package org.scribe.builder.api; + +import org.scribe.extractors.*; +import org.scribe.utils.*; +import org.scribe.model.*; + +/** + * @author Boris G. Tsirkin + * @since 20.4.2011 + */ +public class VkontakteApi extends DefaultApi20 +{ + private static final String AUTHORIZE_URL = "https://oauth.vk.com/authorize?client_id=%s&redirect_uri=%s&response_type=code"; + private static final String SCOPED_AUTHORIZE_URL = String.format("%s&scope=%%s", AUTHORIZE_URL); + + @Override + public String getAccessTokenEndpoint() + { + return "https://api.vkontakte.ru/oauth/access_token"; + } + + @Override + public String getAuthorizationUrl(OAuthConfig config) + { + Preconditions.checkValidUrl(config.getCallback(), "Valid url is required for a callback. Vkontakte does not support OOB"); + if(config.hasScope())// Appending scope if present + { + return String.format(SCOPED_AUTHORIZE_URL, config.getApiKey(), OAuthEncoder.encode(config.getCallback()), OAuthEncoder.encode(config.getScope())); + } + else + { + return String.format(AUTHORIZE_URL, config.getApiKey(), OAuthEncoder.encode(config.getCallback())); + } + } + + @Override + public AccessTokenExtractor getAccessTokenExtractor() + { + return new JsonTokenExtractor(); + } +} diff --git a/src/main/resources/scribe-java-project/src/main/java/org/scribe/builder/api/XingApi.java b/src/main/resources/scribe-java-project/src/main/java/org/scribe/builder/api/XingApi.java new file mode 100755 index 0000000..ec8823e --- /dev/null +++ b/src/main/resources/scribe-java-project/src/main/java/org/scribe/builder/api/XingApi.java @@ -0,0 +1,27 @@ +package org.scribe.builder.api; + +import org.scribe.model.*; + +public class XingApi extends DefaultApi10a +{ + private static final String AUTHORIZE_URL = "https://api.xing.com/v1/authorize?oauth_token=%s"; + + @Override + public String getAccessTokenEndpoint() + { + return "https://api.xing.com/v1/access_token"; + } + + @Override + public String getRequestTokenEndpoint() + { + return "https://api.xing.com/v1/request_token"; + } + + @Override + public String getAuthorizationUrl(Token requestToken) + { + return String.format(AUTHORIZE_URL, requestToken.getToken()); + } + +} diff --git a/src/main/resources/scribe-java-project/src/main/java/org/scribe/builder/api/YahooApi.java b/src/main/resources/scribe-java-project/src/main/java/org/scribe/builder/api/YahooApi.java new file mode 100644 index 0000000..e8a29a7 --- /dev/null +++ b/src/main/resources/scribe-java-project/src/main/java/org/scribe/builder/api/YahooApi.java @@ -0,0 +1,26 @@ +package org.scribe.builder.api; + +import org.scribe.model.Token; + +public class YahooApi extends DefaultApi10a +{ + private static final String AUTHORIZE_URL = "https://api.login.yahoo.com/oauth/v2/request_auth?oauth_token=%s"; + + @Override + public String getAccessTokenEndpoint() + { + return "https://api.login.yahoo.com/oauth/v2/get_token"; + } + + @Override + public String getRequestTokenEndpoint() + { + return "https://api.login.yahoo.com/oauth/v2/get_request_token"; + } + + @Override + public String getAuthorizationUrl(Token requestToken) + { + return String.format(AUTHORIZE_URL, requestToken.getToken()); + } +} diff --git a/src/main/resources/scribe-java-project/src/main/java/org/scribe/builder/api/YammerApi.java b/src/main/resources/scribe-java-project/src/main/java/org/scribe/builder/api/YammerApi.java new file mode 100644 index 0000000..e06543d --- /dev/null +++ b/src/main/resources/scribe-java-project/src/main/java/org/scribe/builder/api/YammerApi.java @@ -0,0 +1,33 @@ +package org.scribe.builder.api; + +import org.scribe.model.*; +import org.scribe.services.*; + +public class YammerApi extends DefaultApi10a +{ + private static final String AUTHORIZATION_URL = "https://www.yammer.com/oauth/authorize?oauth_token=%s"; + + @Override + public String getRequestTokenEndpoint() + { + return "https://www.yammer.com/oauth/request_token"; + } + + @Override + public String getAccessTokenEndpoint() + { + return "https://www.yammer.com/oauth/access_token"; + } + + @Override + public String getAuthorizationUrl(Token requestToken) + { + return String.format(AUTHORIZATION_URL, requestToken.getToken()); + } + + @Override + public SignatureService getSignatureService() + { + return new PlaintextSignatureService(); + } +} diff --git a/src/main/resources/scribe-java-project/src/main/java/org/scribe/exceptions/OAuthConnectionException.java b/src/main/resources/scribe-java-project/src/main/java/org/scribe/exceptions/OAuthConnectionException.java new file mode 100644 index 0000000..918de81 --- /dev/null +++ b/src/main/resources/scribe-java-project/src/main/java/org/scribe/exceptions/OAuthConnectionException.java @@ -0,0 +1,14 @@ +package org.scribe.exceptions; + +/** + * @author: Pablo Fernandez + */ +public class OAuthConnectionException extends OAuthException +{ + private static final String MSG = "There was a problem while creating a connection to the remote service."; + + public OAuthConnectionException(Exception e) + { + super(MSG, e); + } +} diff --git a/src/main/resources/scribe-java-project/src/main/java/org/scribe/exceptions/OAuthException.java b/src/main/resources/scribe-java-project/src/main/java/org/scribe/exceptions/OAuthException.java new file mode 100644 index 0000000..85f49d9 --- /dev/null +++ b/src/main/resources/scribe-java-project/src/main/java/org/scribe/exceptions/OAuthException.java @@ -0,0 +1,33 @@ +package org.scribe.exceptions; + +/** + * Default scribe exception. + * Represents a problem in the OAuth signing process + * + * @author Pablo Fernandez + */ +public class OAuthException extends RuntimeException +{ + + /** + * Default constructor + * @param message message explaining what went wrong + * @param e original exception + */ + public OAuthException(String message, Exception e) + { + super(message, e); + } + + /** + * No-exception constructor. Used when there is no original exception + * + * @param message message explaining what went wrong + */ + public OAuthException(String message) + { + super(message, null); + } + + private static final long serialVersionUID = 1L; +} diff --git a/src/main/resources/scribe-java-project/src/main/java/org/scribe/exceptions/OAuthParametersMissingException.java b/src/main/resources/scribe-java-project/src/main/java/org/scribe/exceptions/OAuthParametersMissingException.java new file mode 100644 index 0000000..8407ce4 --- /dev/null +++ b/src/main/resources/scribe-java-project/src/main/java/org/scribe/exceptions/OAuthParametersMissingException.java @@ -0,0 +1,26 @@ +package org.scribe.exceptions; + +import org.scribe.model.*; + +/** + * Specialized exception that represents a missing OAuth parameter. + * + * @author Pablo Fernandez + */ +public class OAuthParametersMissingException extends OAuthException +{ + + private static final long serialVersionUID = 1745308760111976671L; + private static final String MSG = "Could not find oauth parameters in request: %s. " + + "OAuth parameters must be specified with the addOAuthParameter() method"; + + /** + * Default constructor. + * + * @param request OAuthRequest that caused the error + */ + public OAuthParametersMissingException(OAuthRequest request) + { + super(String.format(MSG, request)); + } +} diff --git a/src/main/resources/scribe-java-project/src/main/java/org/scribe/exceptions/OAuthSignatureException.java b/src/main/resources/scribe-java-project/src/main/java/org/scribe/exceptions/OAuthSignatureException.java new file mode 100644 index 0000000..94692be --- /dev/null +++ b/src/main/resources/scribe-java-project/src/main/java/org/scribe/exceptions/OAuthSignatureException.java @@ -0,0 +1,24 @@ +package org.scribe.exceptions; + +/** + * Specialized exception that represents a problem in the signature + * + * @author Pablo Fernandez + */ +public class OAuthSignatureException extends OAuthException +{ + private static final long serialVersionUID = 1L; + private static final String MSG = "Error while signing string: %s"; + + /** + * Default constructor + * + * @param stringToSign plain string that gets signed (HMAC-SHA, etc) + * @param e original exception + */ + public OAuthSignatureException(String stringToSign, Exception e) + { + super(String.format(MSG, stringToSign), e); + } + +} diff --git a/src/main/resources/scribe-java-project/src/main/java/org/scribe/extractors/AccessTokenExtractor.java b/src/main/resources/scribe-java-project/src/main/java/org/scribe/extractors/AccessTokenExtractor.java new file mode 100644 index 0000000..3c0dd34 --- /dev/null +++ b/src/main/resources/scribe-java-project/src/main/java/org/scribe/extractors/AccessTokenExtractor.java @@ -0,0 +1,19 @@ +package org.scribe.extractors; + +import org.scribe.model.*; + +/** + * Simple command object that extracts a {@link Token} from a String + * + * @author Pablo Fernandez + */ +public interface AccessTokenExtractor +{ + /** + * Extracts the access token from the contents of an Http Response + * + * @param response the contents of the response + * @return OAuth access token + */ + public Token extract(String response); +} diff --git a/src/main/resources/scribe-java-project/src/main/java/org/scribe/extractors/BaseStringExtractor.java b/src/main/resources/scribe-java-project/src/main/java/org/scribe/extractors/BaseStringExtractor.java new file mode 100644 index 0000000..83ddd10 --- /dev/null +++ b/src/main/resources/scribe-java-project/src/main/java/org/scribe/extractors/BaseStringExtractor.java @@ -0,0 +1,21 @@ +package org.scribe.extractors; + +import org.scribe.model.*; + +/** + * Simple command object that extracts a base string from a {@link OAuthRequest} + * + * @author Pablo Fernandez + */ +public interface BaseStringExtractor +{ + /** + * Extracts an url-encoded base string from the {@link OAuthRequest}. + * + * See the oauth spec for more info on this. + * + * @param request the OAuthRequest + * @return the url-encoded base string + */ + String extract(OAuthRequest request); +} diff --git a/src/main/resources/scribe-java-project/src/main/java/org/scribe/extractors/BaseStringExtractorImpl.java b/src/main/resources/scribe-java-project/src/main/java/org/scribe/extractors/BaseStringExtractorImpl.java new file mode 100644 index 0000000..ca21a0d --- /dev/null +++ b/src/main/resources/scribe-java-project/src/main/java/org/scribe/extractors/BaseStringExtractorImpl.java @@ -0,0 +1,48 @@ +package org.scribe.extractors; + +import org.scribe.exceptions.*; +import org.scribe.model.*; +import org.scribe.utils.*; + +/** + * Default implementation of {@link BaseStringExtractor}. Conforms to OAuth 1.0a + * + * @author Pablo Fernandez + * + */ +public class BaseStringExtractorImpl implements BaseStringExtractor +{ + + private static final String AMPERSAND_SEPARATED_STRING = "%s&%s&%s"; + + /** + * {@inheritDoc} + */ + public String extract(OAuthRequest request) + { + checkPreconditions(request); + String verb = OAuthEncoder.encode(request.getVerb().name()); + String url = OAuthEncoder.encode(request.getSanitizedUrl()); + String params = getSortedAndEncodedParams(request); + return String.format(AMPERSAND_SEPARATED_STRING, verb, url, params); + } + + private String getSortedAndEncodedParams(OAuthRequest request) + { + ParameterList params = new ParameterList(); + params.addAll(request.getQueryStringParams()); + params.addAll(request.getBodyParams()); + params.addAll(new ParameterList(request.getOauthParameters())); + return params.sort().asOauthBaseString(); + } + + private void checkPreconditions(OAuthRequest request) + { + Preconditions.checkNotNull(request, "Cannot extract base string from null object"); + + if (request.getOauthParameters() == null || request.getOauthParameters().size() <= 0) + { + throw new OAuthParametersMissingException(request); + } + } +} diff --git a/src/main/resources/scribe-java-project/src/main/java/org/scribe/extractors/HeaderExtractor.java b/src/main/resources/scribe-java-project/src/main/java/org/scribe/extractors/HeaderExtractor.java new file mode 100644 index 0000000..2bc1f8b --- /dev/null +++ b/src/main/resources/scribe-java-project/src/main/java/org/scribe/extractors/HeaderExtractor.java @@ -0,0 +1,19 @@ +package org.scribe.extractors; + +import org.scribe.model.*; + +/** + * Simple command object that generates an OAuth Authorization header to include in the request. + * + * @author Pablo Fernandez + */ +public interface HeaderExtractor +{ + /** + * Generates an OAuth 'Authorization' Http header to include in requests as the signature. + * + * @param request the OAuthRequest to inspect and generate the header + * @return the Http header value + */ + String extract(OAuthRequest request); +} diff --git a/src/main/resources/scribe-java-project/src/main/java/org/scribe/extractors/HeaderExtractorImpl.java b/src/main/resources/scribe-java-project/src/main/java/org/scribe/extractors/HeaderExtractorImpl.java new file mode 100644 index 0000000..85f4526 --- /dev/null +++ b/src/main/resources/scribe-java-project/src/main/java/org/scribe/extractors/HeaderExtractorImpl.java @@ -0,0 +1,58 @@ +package org.scribe.extractors; + +import java.util.*; + +import org.scribe.exceptions.*; +import org.scribe.model.*; +import org.scribe.utils.*; + +/** + * Default implementation of {@link HeaderExtractor}. Conforms to OAuth 1.0a + * + * @author Pablo Fernandez + * + */ +public class HeaderExtractorImpl implements HeaderExtractor +{ + private static final String PARAM_SEPARATOR = ", "; + private static final String PREAMBLE = "OAuth "; + public static final int ESTIMATED_PARAM_LENGTH = 20; + + /** + * {@inheritDoc} + */ + public String extract(OAuthRequest request) + { + checkPreconditions(request); + Map parameters = request.getOauthParameters(); + StringBuilder header = new StringBuilder(parameters.size() * ESTIMATED_PARAM_LENGTH); + header.append(PREAMBLE); + for (Map.Entry entry : parameters.entrySet()) + { + if(header.length() > PREAMBLE.length()) + { + header.append(PARAM_SEPARATOR); + } + header.append(String.format("%s=\"%s\"", entry.getKey(), OAuthEncoder.encode(entry.getValue()))); + } + + if (request.getRealm() != null && !request.getRealm().isEmpty()) + { + header.append(PARAM_SEPARATOR); + header.append(String.format("%s=\"%s\"", OAuthConstants.REALM, request.getRealm())); + } + + return header.toString(); + } + + private void checkPreconditions(OAuthRequest request) + { + Preconditions.checkNotNull(request, "Cannot extract a header from a null object"); + + if (request.getOauthParameters() == null || request.getOauthParameters().size() <= 0) + { + throw new OAuthParametersMissingException(request); + } + } + +} diff --git a/src/main/resources/scribe-java-project/src/main/java/org/scribe/extractors/JsonTokenExtractor.java b/src/main/resources/scribe-java-project/src/main/java/org/scribe/extractors/JsonTokenExtractor.java new file mode 100644 index 0000000..b51091f --- /dev/null +++ b/src/main/resources/scribe-java-project/src/main/java/org/scribe/extractors/JsonTokenExtractor.java @@ -0,0 +1,27 @@ +package org.scribe.extractors; + +import java.util.regex.*; + +import org.scribe.exceptions.*; +import org.scribe.model.*; +import org.scribe.utils.*; + +public class JsonTokenExtractor implements AccessTokenExtractor +{ + private Pattern accessTokenPattern = Pattern.compile("\"access_token\":\\s*\"(\\S*?)\""); + + public Token extract(String response) + { + Preconditions.checkEmptyString(response, "Cannot extract a token from a null or empty String"); + Matcher matcher = accessTokenPattern.matcher(response); + if(matcher.find()) + { + return new Token(matcher.group(1), "", response); + } + else + { + throw new OAuthException("Cannot extract an access token. Response was: " + response); + } + } + +} \ No newline at end of file diff --git a/src/main/resources/scribe-java-project/src/main/java/org/scribe/extractors/RequestTokenExtractor.java b/src/main/resources/scribe-java-project/src/main/java/org/scribe/extractors/RequestTokenExtractor.java new file mode 100644 index 0000000..1830212 --- /dev/null +++ b/src/main/resources/scribe-java-project/src/main/java/org/scribe/extractors/RequestTokenExtractor.java @@ -0,0 +1,19 @@ +package org.scribe.extractors; + +import org.scribe.model.*; + +/** + * Simple command object that extracts a {@link Token} from a String + * + * @author Pablo Fernandez + */ +public interface RequestTokenExtractor +{ + /** + * Extracts the request token from the contents of an Http Response + * + * @param response the contents of the response + * @return OAuth access token + */ + public Token extract(String response); +} diff --git a/src/main/resources/scribe-java-project/src/main/java/org/scribe/extractors/TokenExtractor20Impl.java b/src/main/resources/scribe-java-project/src/main/java/org/scribe/extractors/TokenExtractor20Impl.java new file mode 100644 index 0000000..1eb22ad --- /dev/null +++ b/src/main/resources/scribe-java-project/src/main/java/org/scribe/extractors/TokenExtractor20Impl.java @@ -0,0 +1,36 @@ +package org.scribe.extractors; + +import java.util.regex.*; + +import org.scribe.exceptions.*; +import org.scribe.model.*; +import org.scribe.utils.*; + +/** + * Default implementation of {@AccessTokenExtractor}. Conforms to OAuth 2.0 + * + */ +public class TokenExtractor20Impl implements AccessTokenExtractor +{ + private static final String TOKEN_REGEX = "access_token=([^&]+)"; + private static final String EMPTY_SECRET = ""; + + /** + * {@inheritDoc} + */ + public Token extract(String response) + { + Preconditions.checkEmptyString(response, "Response body is incorrect. Can't extract a token from an empty string"); + + Matcher matcher = Pattern.compile(TOKEN_REGEX).matcher(response); + if (matcher.find()) + { + String token = OAuthEncoder.decode(matcher.group(1)); + return new Token(token, EMPTY_SECRET, response); + } + else + { + throw new OAuthException("Response body is incorrect. Can't extract a token from this: '" + response + "'", null); + } + } +} diff --git a/src/main/resources/scribe-java-project/src/main/java/org/scribe/extractors/TokenExtractorImpl.java b/src/main/resources/scribe-java-project/src/main/java/org/scribe/extractors/TokenExtractorImpl.java new file mode 100644 index 0000000..ba1784b --- /dev/null +++ b/src/main/resources/scribe-java-project/src/main/java/org/scribe/extractors/TokenExtractorImpl.java @@ -0,0 +1,44 @@ +package org.scribe.extractors; + +import java.util.regex.*; + +import org.scribe.exceptions.*; +import org.scribe.model.*; +import org.scribe.utils.*; + +/** + * Default implementation of {@RequestTokenExtractor} and {@AccessTokenExtractor}. Conforms to OAuth 1.0a + * + * The process for extracting access and request tokens is similar so this class can do both things. + * + * @author Pablo Fernandez + */ +public class TokenExtractorImpl implements RequestTokenExtractor, AccessTokenExtractor +{ + private static final Pattern TOKEN_REGEX = Pattern.compile("oauth_token=([^&]+)"); + private static final Pattern SECRET_REGEX = Pattern.compile("oauth_token_secret=([^&]*)"); + + /** + * {@inheritDoc} + */ + public Token extract(String response) + { + Preconditions.checkEmptyString(response, "Response body is incorrect. Can't extract a token from an empty string"); + String token = extract(response, TOKEN_REGEX); + String secret = extract(response, SECRET_REGEX); + return new Token(token, secret, response); + } + + private String extract(String response, Pattern p) + { + Matcher matcher = p.matcher(response); + if (matcher.find() && matcher.groupCount() >= 1) + { + return OAuthEncoder.decode(matcher.group(1)); + } + else + { + throw new OAuthException("Response body is incorrect. Can't extract token and secret from this: '" + response + "'", null); + } + } +} diff --git a/src/main/resources/scribe-java-project/src/main/java/org/scribe/model/OAuthConfig.java b/src/main/resources/scribe-java-project/src/main/java/org/scribe/model/OAuthConfig.java new file mode 100644 index 0000000..374c958 --- /dev/null +++ b/src/main/resources/scribe-java-project/src/main/java/org/scribe/model/OAuthConfig.java @@ -0,0 +1,79 @@ +package org.scribe.model; + +import java.io.*; + +/** + * Parameter object that groups OAuth config values + * + * @author Pablo Fernandez + */ +public class OAuthConfig +{ + private final String apiKey; + private final String apiSecret; + private final String callback; + private final SignatureType signatureType; + private final String scope; + private final OutputStream debugStream; + + public OAuthConfig(String key, String secret) + { + this(key, secret, null, null, null, null); + } + + public OAuthConfig(String key, String secret, String callback, SignatureType type, String scope, OutputStream stream) + { + this.apiKey = key; + this.apiSecret = secret; + this.callback = callback; + this.signatureType = type; + this.scope = scope; + this.debugStream = stream; + } + + public String getApiKey() + { + return apiKey; + } + + public String getApiSecret() + { + return apiSecret; + } + + public String getCallback() + { + return callback; + } + + public SignatureType getSignatureType() + { + return signatureType; + } + + public String getScope() + { + return scope; + } + + public boolean hasScope() + { + return scope != null; + } + + public void log(String message) + { + if (debugStream != null) + { + message = message + "\n"; + try + { + debugStream.write(message.getBytes("UTF8")); + } + catch (Exception e) + { + throw new RuntimeException("there were problems while writting to the debug stream", e); + } + } + } +} diff --git a/src/main/resources/scribe-java-project/src/main/java/org/scribe/model/OAuthConstants.java b/src/main/resources/scribe-java-project/src/main/java/org/scribe/model/OAuthConstants.java new file mode 100644 index 0000000..c442dee --- /dev/null +++ b/src/main/resources/scribe-java-project/src/main/java/org/scribe/model/OAuthConstants.java @@ -0,0 +1,52 @@ +/* +Copyright 2010 Pablo Fernandez + +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.scribe.model; + +/** + * This class contains OAuth constants, used project-wide + * + * @author Pablo Fernandez + */ +public class OAuthConstants +{ + private OAuthConstants(){} + + public static final String TIMESTAMP = "oauth_timestamp"; + public static final String SIGN_METHOD = "oauth_signature_method"; + public static final String SIGNATURE = "oauth_signature"; + public static final String CONSUMER_SECRET = "oauth_consumer_secret"; + public static final String CONSUMER_KEY = "oauth_consumer_key"; + public static final String CALLBACK = "oauth_callback"; + public static final String VERSION = "oauth_version"; + public static final String NONCE = "oauth_nonce"; + public static final String REALM = "realm"; + public static final String PARAM_PREFIX = "oauth_"; + public static final String TOKEN = "oauth_token"; + public static final String TOKEN_SECRET = "oauth_token_secret"; + public static final String OUT_OF_BAND = "oob"; + public static final String VERIFIER = "oauth_verifier"; + public static final String HEADER = "Authorization"; + public static final Token EMPTY_TOKEN = new Token("", ""); + public static final String SCOPE = "scope"; + + //OAuth 2.0 + public static final String ACCESS_TOKEN = "access_token"; + public static final String CLIENT_ID = "client_id"; + public static final String CLIENT_SECRET = "client_secret"; + public static final String REDIRECT_URI = "redirect_uri"; + public static final String CODE = "code"; + +} diff --git a/src/main/resources/scribe-java-project/src/main/java/org/scribe/model/OAuthRequest.java b/src/main/resources/scribe-java-project/src/main/java/org/scribe/model/OAuthRequest.java new file mode 100644 index 0000000..d3b2e5a --- /dev/null +++ b/src/main/resources/scribe-java-project/src/main/java/org/scribe/model/OAuthRequest.java @@ -0,0 +1,80 @@ +package org.scribe.model; + +import java.util.*; + +/** + * The representation of an OAuth HttpRequest. + * + * Adds OAuth-related functionality to the {@link Request} + * + * @author Pablo Fernandez + */ +public class OAuthRequest extends Request +{ + private static final String OAUTH_PREFIX = "oauth_"; + private Map oauthParameters; + private String realm; + + /** + * Default constructor. + * + * @param verb Http verb/method + * @param url resource URL + */ + public OAuthRequest(Verb verb, String url) + { + super(verb, url); + this.oauthParameters = new HashMap(); + } + + /** + * Adds an OAuth parameter. + * + * @param key name of the parameter + * @param value value of the parameter + * + * @throws IllegalArgumentException if the parameter is not an OAuth parameter + */ + public void addOAuthParameter(String key, String value) + { + oauthParameters.put(checkKey(key), value); + } + + private String checkKey(String key) + { + if (key.startsWith(OAUTH_PREFIX) || key.equals(OAuthConstants.SCOPE)) + { + return key; + } + else + { + throw new IllegalArgumentException(String.format("OAuth parameters must either be '%s' or start with '%s'", OAuthConstants.SCOPE, OAUTH_PREFIX)); + } + } + + /** + * Returns the {@link Map} containing the key-value pair of parameters. + * + * @return parameters as map + */ + public Map getOauthParameters() + { + return oauthParameters; + } + + public void setRealm(String realm) + { + this.realm = realm; + } + + public String getRealm() + { + return realm; + } + + @Override + public String toString() + { + return String.format("@OAuthRequest(%s, %s)", getVerb(), getUrl()); + } +} diff --git a/src/main/resources/scribe-java-project/src/main/java/org/scribe/model/Parameter.java b/src/main/resources/scribe-java-project/src/main/java/org/scribe/model/Parameter.java new file mode 100644 index 0000000..f8f3b81 --- /dev/null +++ b/src/main/resources/scribe-java-project/src/main/java/org/scribe/model/Parameter.java @@ -0,0 +1,47 @@ +package org.scribe.model; + +import org.scribe.utils.*; + +/** + * @author: Pablo Fernandez + */ +public class Parameter implements Comparable +{ + private static final String UTF = "UTF8"; + + private final String key; + private final String value; + + public Parameter(String key, String value) + { + this.key = key; + this.value = value; + } + + public String asUrlEncodedPair() + { + return OAuthEncoder.encode(key).concat("=").concat(OAuthEncoder.encode(value)); + } + + public boolean equals(Object other) + { + if(other == null) return false; + if(other == this) return true; + if(!(other instanceof Parameter)) return false; + + Parameter otherParam = (Parameter) other; + return otherParam.key.equals(key) && otherParam.value.equals(value); + } + + public int hashCode() + { + return key.hashCode() + value.hashCode(); + } + + public int compareTo(Parameter parameter) + { + int keyDiff = key.compareTo(parameter.key); + + return keyDiff != 0 ? keyDiff : value.compareTo(parameter.value); + } +} diff --git a/src/main/resources/scribe-java-project/src/main/java/org/scribe/model/ParameterList.java b/src/main/resources/scribe-java-project/src/main/java/org/scribe/model/ParameterList.java new file mode 100644 index 0000000..b365cba --- /dev/null +++ b/src/main/resources/scribe-java-project/src/main/java/org/scribe/model/ParameterList.java @@ -0,0 +1,114 @@ +package org.scribe.model; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.Map; +import org.scribe.utils.OAuthEncoder; +import org.scribe.utils.Preconditions; + +/** + * @author: Pablo Fernandez + */ +public class ParameterList +{ + private static final char QUERY_STRING_SEPARATOR = '?'; + private static final String PARAM_SEPARATOR = "&"; + private static final String PAIR_SEPARATOR = "="; + private static final String EMPTY_STRING = ""; + + private final List params; + + public ParameterList() + { + params = new ArrayList(); + } + + ParameterList(List params) + { + this.params = new ArrayList(params); + } + + public ParameterList(Map map) + { + this(); + for(Map.Entry entry : map.entrySet()) + { + params.add(new Parameter(entry.getKey(), entry.getValue())); + } + } + + public void add(String key, String value) + { + params.add(new Parameter(key, value)); + } + + public String appendTo(String url) + { + Preconditions.checkNotNull(url, "Cannot append to null URL"); + String queryString = asFormUrlEncodedString(); + if (queryString.equals(EMPTY_STRING)) + { + return url; + } + else + { + url += url.indexOf(QUERY_STRING_SEPARATOR) != -1 ? PARAM_SEPARATOR : QUERY_STRING_SEPARATOR; + url += queryString; + return url; + } + } + + public String asOauthBaseString() + { + return OAuthEncoder.encode(asFormUrlEncodedString()); + } + + public String asFormUrlEncodedString() + { + if (params.size() == 0) return EMPTY_STRING; + + StringBuilder builder = new StringBuilder(); + for(Parameter p : params) + { + builder.append('&').append(p.asUrlEncodedPair()); + } + return builder.toString().substring(1); + } + + public void addAll(ParameterList other) + { + params.addAll(other.params); + } + + public void addQuerystring(String queryString) + { + if (queryString != null && queryString.length() > 0) + { + for (String param : queryString.split(PARAM_SEPARATOR)) + { + String pair[] = param.split(PAIR_SEPARATOR); + String key = OAuthEncoder.decode(pair[0]); + String value = pair.length > 1 ? OAuthEncoder.decode(pair[1]) : EMPTY_STRING; + params.add(new Parameter(key, value)); + } + } + } + + public boolean contains(Parameter param) + { + return params.contains(param); + } + + public int size() + { + return params.size(); + } + + public ParameterList sort() + { + ParameterList sorted = new ParameterList(params); + Collections.sort(sorted.params); + return sorted; + } +} diff --git a/src/main/resources/scribe-java-project/src/main/java/org/scribe/model/Request.java b/src/main/resources/scribe-java-project/src/main/java/org/scribe/model/Request.java new file mode 100644 index 0000000..e48578e --- /dev/null +++ b/src/main/resources/scribe-java-project/src/main/java/org/scribe/model/Request.java @@ -0,0 +1,390 @@ +package org.scribe.model; + +import java.io.*; +import java.net.*; +import java.nio.charset.*; +import java.util.*; +import java.util.concurrent.*; + +import org.scribe.exceptions.*; + +/** + * Represents an HTTP Request object + * + * @author Pablo Fernandez + */ +public class Request +{ + private static final String CONTENT_LENGTH = "Content-Length"; + private static final String CONTENT_TYPE = "Content-Type"; + private static RequestTuner NOOP = new RequestTuner() { + @Override public void tune(Request _){} + }; + public static final String DEFAULT_CONTENT_TYPE = "application/x-www-form-urlencoded"; + + private String url; + private Verb verb; + private ParameterList querystringParams; + private ParameterList bodyParams; + private Map headers; + private String payload = null; + private HttpURLConnection connection; + private String charset; + private byte[] bytePayload = null; + private boolean connectionKeepAlive = false; + private boolean followRedirects = true; + private Long connectTimeout = null; + private Long readTimeout = null; + + /** + * Creates a new Http Request + * + * @param verb Http Verb (GET, POST, etc) + * @param url url with optional querystring parameters. + */ + public Request(Verb verb, String url) + { + this.verb = verb; + this.url = url; + this.querystringParams = new ParameterList(); + this.bodyParams = new ParameterList(); + this.headers = new HashMap(); + } + + /** + * Execute the request and return a {@link Response} + * + * @return Http Response + * @throws RuntimeException + * if the connection cannot be created. + */ + public Response send(RequestTuner tuner) + { + try + { + createConnection(); + return doSend(tuner); + } + catch (Exception e) + { + throw new OAuthConnectionException(e); + } + } + + public Response send() + { + return send(NOOP); + } + + private void createConnection() throws IOException + { + String completeUrl = getCompleteUrl(); + if (connection == null) + { + System.setProperty("http.keepAlive", connectionKeepAlive ? "true" : "false"); + connection = (HttpURLConnection) new URL(completeUrl).openConnection(); + connection.setInstanceFollowRedirects(followRedirects); + } + } + + /** + * Returns the complete url (host + resource + encoded querystring parameters). + * + * @return the complete url. + */ + public String getCompleteUrl() + { + return querystringParams.appendTo(url); + } + + Response doSend(RequestTuner tuner) throws IOException + { + connection.setRequestMethod(this.verb.name()); + if (connectTimeout != null) + { + connection.setConnectTimeout(connectTimeout.intValue()); + } + if (readTimeout != null) + { + connection.setReadTimeout(readTimeout.intValue()); + } + addHeaders(connection); + if (verb.equals(Verb.PUT) || verb.equals(Verb.POST)) + { + addBody(connection, getByteBodyContents()); + } + tuner.tune(this); + return new Response(connection); + } + + void addHeaders(HttpURLConnection conn) + { + for (String key : headers.keySet()) + conn.setRequestProperty(key, headers.get(key)); + } + + void addBody(HttpURLConnection conn, byte[] content) throws IOException + { + conn.setRequestProperty(CONTENT_LENGTH, String.valueOf(content.length)); + + // Set default content type if none is set. + if (conn.getRequestProperty(CONTENT_TYPE) == null) + { + conn.setRequestProperty(CONTENT_TYPE, DEFAULT_CONTENT_TYPE); + } + conn.setDoOutput(true); + conn.getOutputStream().write(content); + } + + /** + * Add an HTTP Header to the Request + * + * @param key the header name + * @param value the header value + */ + public void addHeader(String key, String value) + { + this.headers.put(key, value); + } + + /** + * Add a body Parameter (for POST/ PUT Requests) + * + * @param key the parameter name + * @param value the parameter value + */ + public void addBodyParameter(String key, String value) + { + this.bodyParams.add(key, value); + } + + /** + * Add a QueryString parameter + * + * @param key the parameter name + * @param value the parameter value + */ + public void addQuerystringParameter(String key, String value) + { + this.querystringParams.add(key, value); + } + + /** + * Add body payload. + * + * This method is used when the HTTP body is not a form-url-encoded string, + * but another thing. Like for example XML. + * + * Note: The contents are not part of the OAuth signature + * + * @param payload the body of the request + */ + public void addPayload(String payload) + { + this.payload = payload; + } + + /** + * Overloaded version for byte arrays + * + * @param payload + */ + public void addPayload(byte[] payload) + { + this.bytePayload = payload.clone(); + } + + /** + * Get a {@link ParameterList} with the query string parameters. + * + * @return a {@link ParameterList} containing the query string parameters. + * @throws OAuthException if the request URL is not valid. + */ + public ParameterList getQueryStringParams() + { + try + { + ParameterList result = new ParameterList(); + String queryString = new URL(url).getQuery(); + result.addQuerystring(queryString); + result.addAll(querystringParams); + return result; + } + catch (MalformedURLException mue) + { + throw new OAuthException("Malformed URL", mue); + } + } + + /** + * Obtains a {@link ParameterList} of the body parameters. + * + * @return a {@link ParameterList}containing the body parameters. + */ + public ParameterList getBodyParams() + { + return bodyParams; + } + + /** + * Obtains the URL of the HTTP Request. + * + * @return the original URL of the HTTP Request + */ + public String getUrl() + { + return url; + } + + /** + * Returns the URL without the default port and the query string part. + * + * @return the OAuth-sanitized URL + */ + public String getSanitizedUrl() + { + if(url.startsWith("http://") && (url.endsWith(":80") || url.contains(":80/"))){ + return url.replaceAll("\\?.*", "").replaceAll(":80", ""); + } + else if(url.startsWith("https://") && (url.endsWith(":443") || url.contains(":443/"))){ + return url.replaceAll("\\?.*", "").replaceAll(":443", ""); + } + else{ + return url.replaceAll("\\?.*", ""); + } + } + + /** + * Returns the body of the request + * + * @return form encoded string + * @throws OAuthException if the charset chosen is not supported + */ + public String getBodyContents() + { + try + { + return new String(getByteBodyContents(),getCharset()); + } + catch(UnsupportedEncodingException uee) + { + throw new OAuthException("Unsupported Charset: "+charset, uee); + } + } + + byte[] getByteBodyContents() + { + if (bytePayload != null) return bytePayload; + String body = (payload != null) ? payload : bodyParams.asFormUrlEncodedString(); + try + { + return body.getBytes(getCharset()); + } + catch(UnsupportedEncodingException uee) + { + throw new OAuthException("Unsupported Charset: "+getCharset(), uee); + } + } + + /** + * Returns the HTTP Verb + * + * @return the verb + */ + public Verb getVerb() + { + return verb; + } + + /** + * Returns the connection headers as a {@link Map} + * + * @return map of headers + */ + public Map getHeaders() + { + return headers; + } + + /** + * Returns the connection charset. Defaults to {@link Charset} defaultCharset if not set + * + * @return charset + */ + public String getCharset() + { + return charset == null ? Charset.defaultCharset().name() : charset; + } + + /** + * Sets the connect timeout for the underlying {@link HttpURLConnection} + * + * @param duration duration of the timeout + * + * @param unit unit of time (milliseconds, seconds, etc) + */ + public void setConnectTimeout(int duration, TimeUnit unit) + { + this.connectTimeout = unit.toMillis(duration); + } + + /** + * Sets the read timeout for the underlying {@link HttpURLConnection} + * + * @param duration duration of the timeout + * + * @param unit unit of time (milliseconds, seconds, etc) + */ + public void setReadTimeout(int duration, TimeUnit unit) + { + this.readTimeout = unit.toMillis(duration); + } + + /** + * Set the charset of the body of the request + * + * @param charsetName name of the charset of the request + */ + public void setCharset(String charsetName) + { + this.charset = charsetName; + } + + /** + * Sets whether the underlying Http Connection is persistent or not. + * + * @see http://download.oracle.com/javase/1.5.0/docs/guide/net/http-keepalive.html + * @param connectionKeepAlive + */ + public void setConnectionKeepAlive(boolean connectionKeepAlive) + { + this.connectionKeepAlive = connectionKeepAlive; + } + + /** + * Sets whether the underlying Http Connection follows redirects or not. + * + * Defaults to true (follow redirects) + * + * @see http://docs.oracle.com/javase/6/docs/api/java/net/HttpURLConnection.html#setInstanceFollowRedirects(boolean) + * @param followRedirects + */ + public void setFollowRedirects(boolean followRedirects) + { + this.followRedirects = followRedirects; + } + + /* + * We need this in order to stub the connection object for test cases + */ + void setConnection(HttpURLConnection connection) + { + this.connection = connection; + } + + @Override + public String toString() + { + return String.format("@Request(%s %s)", getVerb(), getUrl()); + } +} diff --git a/src/main/resources/scribe-java-project/src/main/java/org/scribe/model/RequestTuner.java b/src/main/resources/scribe-java-project/src/main/java/org/scribe/model/RequestTuner.java new file mode 100644 index 0000000..34ea1eb --- /dev/null +++ b/src/main/resources/scribe-java-project/src/main/java/org/scribe/model/RequestTuner.java @@ -0,0 +1,6 @@ +package org.scribe.model; + +public abstract class RequestTuner +{ + public abstract void tune(Request request); +} \ No newline at end of file diff --git a/src/main/resources/scribe-java-project/src/main/java/org/scribe/model/Response.java b/src/main/resources/scribe-java-project/src/main/java/org/scribe/model/Response.java new file mode 100644 index 0000000..d433922 --- /dev/null +++ b/src/main/resources/scribe-java-project/src/main/java/org/scribe/model/Response.java @@ -0,0 +1,126 @@ +package org.scribe.model; + +import java.io.*; +import java.net.*; +import java.util.*; + +import org.scribe.exceptions.*; +import org.scribe.utils.*; + +/** + * Represents an HTTP Response. + * + * @author Pablo Fernandez + */ +public class Response +{ + private static final String EMPTY = ""; + + private int code; + private String message; + private String body; + private InputStream stream; + private Map headers; + + Response(HttpURLConnection connection) throws IOException + { + try + { + connection.connect(); + code = connection.getResponseCode(); + message = connection.getResponseMessage(); + headers = parseHeaders(connection); + stream = isSuccessful() ? connection.getInputStream() : connection.getErrorStream(); + } + catch (UnknownHostException e) + { + throw new OAuthException("The IP address of a host could not be determined.", e); + } + } + + private String parseBodyContents() + { + body = StreamUtils.getStreamContents(getStream()); + return body; + } + + private Map parseHeaders(HttpURLConnection conn) + { + Map headers = new HashMap(); + for (String key : conn.getHeaderFields().keySet()) + { + headers.put(key, conn.getHeaderFields().get(key).get(0)); + } + return headers; + } + + public boolean isSuccessful() + { + return getCode() >= 200 && getCode() < 400; + } + + /** + * Obtains the HTTP Response body + * + * @return response body + */ + public String getBody() + { + return body != null ? body : parseBodyContents(); + } + + /** + * Obtains the meaningful stream of the HttpUrlConnection, either inputStream + * or errorInputStream, depending on the status code + * + * @return input stream / error stream + */ + public InputStream getStream() + { + return stream; + } + + /** + * Obtains the HTTP status code + * + * @return the status code + */ + public int getCode() + { + return code; + } + + /** + * Obtains the HTTP status message. + * Returns null if the message can not be discerned from the response (not valid HTTP) + * + * @return the status message + */ + public String getMessage() + { + return message; + } + + /** + * Obtains a {@link Map} containing the HTTP Response Headers + * + * @return headers + */ + public Map getHeaders() + { + return headers; + } + + /** + * Obtains a single HTTP Header value, or null if undefined + * + * @param name the header name. + * + * @return header value or null. + */ + public String getHeader(String name) + { + return headers.get(name); + } + +} \ No newline at end of file diff --git a/src/main/resources/scribe-java-project/src/main/java/org/scribe/model/SignatureType.java b/src/main/resources/scribe-java-project/src/main/java/org/scribe/model/SignatureType.java new file mode 100644 index 0000000..3440a36 --- /dev/null +++ b/src/main/resources/scribe-java-project/src/main/java/org/scribe/model/SignatureType.java @@ -0,0 +1,7 @@ +package org.scribe.model; + +public enum SignatureType +{ + Header, + QueryString +} diff --git a/src/main/resources/scribe-java-project/src/main/java/org/scribe/model/Token.java b/src/main/resources/scribe-java-project/src/main/java/org/scribe/model/Token.java new file mode 100644 index 0000000..4d8c0ee --- /dev/null +++ b/src/main/resources/scribe-java-project/src/main/java/org/scribe/model/Token.java @@ -0,0 +1,98 @@ +package org.scribe.model; + +import java.io.*; +import org.scribe.utils.*; + +/** + * Represents an OAuth token (either request or access token) and its secret + * + * @author Pablo Fernandez + */ +public class Token implements Serializable +{ + private static final long serialVersionUID = 715000866082812683L; + + private final String token; + private final String secret; + private final String rawResponse; + + /** + * Default constructor + * + * @param token token value. Can't be null. + * @param secret token secret. Can't be null. + */ + public Token(String token, String secret) + { + this(token, secret, null); + } + + public Token(String token, String secret, String rawResponse) + { + Preconditions.checkNotNull(token, "Token can't be null"); + Preconditions.checkNotNull(secret, "Secret can't be null"); + + this.token = token; + this.secret = secret; + this.rawResponse = rawResponse; + } + + public String getToken() + { + return token; + } + + public String getSecret() + { + return secret; + } + + public String getRawResponse() + { + if (rawResponse == null) + { + throw new IllegalStateException("This token object was not constructed by scribe and does not have a rawResponse"); + } + return rawResponse; + } + + @Override + public String toString() + { + return String.format("Token[%s , %s]", token, secret); + } + + /** + * Returns true if the token is empty (token = "", secret = "") + */ + public boolean isEmpty() + { + return "".equals(this.token) && "".equals(this.secret); + } + + /** + * Factory method that returns an empty token (token = "", secret = ""). + * + * Useful for two legged OAuth. + */ + public static Token empty() + { + return new Token("", ""); + } + + @Override + public boolean equals(Object o) + { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + Token that = (Token) o; + return token.equals(that.token) && secret.equals(that.secret); + } + + @Override + public int hashCode() + { + return 31 * token.hashCode() + secret.hashCode(); + } +} diff --git a/src/main/resources/scribe-java-project/src/main/java/org/scribe/model/Verb.java b/src/main/resources/scribe-java-project/src/main/java/org/scribe/model/Verb.java new file mode 100644 index 0000000..ec05731 --- /dev/null +++ b/src/main/resources/scribe-java-project/src/main/java/org/scribe/model/Verb.java @@ -0,0 +1,11 @@ +package org.scribe.model; + +/** + * An enumeration containing the most common HTTP Verbs. + * + * @author Pablo Fernandez + */ +public enum Verb +{ + GET, POST, PUT, DELETE, HEAD, OPTIONS, TRACE +} diff --git a/src/main/resources/scribe-java-project/src/main/java/org/scribe/model/Verifier.java b/src/main/resources/scribe-java-project/src/main/java/org/scribe/model/Verifier.java new file mode 100644 index 0000000..45f0e4e --- /dev/null +++ b/src/main/resources/scribe-java-project/src/main/java/org/scribe/model/Verifier.java @@ -0,0 +1,30 @@ +package org.scribe.model; + +import org.scribe.utils.*; + +/** + * Represents an OAuth verifier code. + * + * @author Pablo Fernandez + */ +public class Verifier +{ + + private final String value; + + /** + * Default constructor. + * + * @param value verifier value + */ + public Verifier(String value) + { + Preconditions.checkNotNull(value, "Must provide a valid string as verifier"); + this.value = value; + } + + public String getValue() + { + return value; + } +} diff --git a/src/main/resources/scribe-java-project/src/main/java/org/scribe/oauth/OAuth10aServiceImpl.java b/src/main/resources/scribe-java-project/src/main/java/org/scribe/oauth/OAuth10aServiceImpl.java new file mode 100644 index 0000000..2b207f5 --- /dev/null +++ b/src/main/resources/scribe-java-project/src/main/java/org/scribe/oauth/OAuth10aServiceImpl.java @@ -0,0 +1,196 @@ +package org.scribe.oauth; + +import java.util.*; + +import org.scribe.builder.api.*; +import org.scribe.model.*; +import org.scribe.services.*; +import org.scribe.utils.*; +import java.util.concurrent.TimeUnit; + +/** + * OAuth 1.0a implementation of {@link OAuthService} + * + * @author Pablo Fernandez + */ +public class OAuth10aServiceImpl implements OAuthService +{ + private static final String VERSION = "1.0"; + + private OAuthConfig config; + private DefaultApi10a api; + + /** + * Default constructor + * + * @param api OAuth1.0a api information + * @param config OAuth 1.0a configuration param object + */ + public OAuth10aServiceImpl(DefaultApi10a api, OAuthConfig config) + { + this.api = api; + this.config = config; + } + + /** + * {@inheritDoc} + */ + public Token getRequestToken(int timeout, TimeUnit unit) + { + return getRequestToken(new TimeoutTuner(timeout, unit)); + } + + public Token getRequestToken() + { + return getRequestToken(2, TimeUnit.SECONDS); + } + + public Token getRequestToken(RequestTuner tuner) + { + config.log("obtaining request token from " + api.getRequestTokenEndpoint()); + OAuthRequest request = new OAuthRequest(api.getRequestTokenVerb(), api.getRequestTokenEndpoint()); + + config.log("setting oauth_callback to " + config.getCallback()); + request.addOAuthParameter(OAuthConstants.CALLBACK, config.getCallback()); + addOAuthParams(request, OAuthConstants.EMPTY_TOKEN); + appendSignature(request); + + config.log("sending request..."); + Response response = request.send(tuner); + String body = response.getBody(); + + config.log("response status code: " + response.getCode()); + config.log("response body: " + body); + return api.getRequestTokenExtractor().extract(body); + } + + private void addOAuthParams(OAuthRequest request, Token token) + { + request.addOAuthParameter(OAuthConstants.TIMESTAMP, api.getTimestampService().getTimestampInSeconds()); + request.addOAuthParameter(OAuthConstants.NONCE, api.getTimestampService().getNonce()); + request.addOAuthParameter(OAuthConstants.CONSUMER_KEY, config.getApiKey()); + request.addOAuthParameter(OAuthConstants.SIGN_METHOD, api.getSignatureService().getSignatureMethod()); + request.addOAuthParameter(OAuthConstants.VERSION, getVersion()); + if(config.hasScope()) request.addOAuthParameter(OAuthConstants.SCOPE, config.getScope()); + request.addOAuthParameter(OAuthConstants.SIGNATURE, getSignature(request, token)); + + config.log("appended additional OAuth parameters: " + MapUtils.toString(request.getOauthParameters())); + } + + /** + * {@inheritDoc} + */ + public Token getAccessToken(Token requestToken, Verifier verifier, int timeout, TimeUnit unit) + { + return getAccessToken(requestToken, verifier, new TimeoutTuner(timeout, unit)); + } + + public Token getAccessToken(Token requestToken, Verifier verifier) + { + return getAccessToken(requestToken, verifier, 2, TimeUnit.SECONDS); + } + + public Token getAccessToken(Token requestToken, Verifier verifier, RequestTuner tuner) + { + config.log("obtaining access token from " + api.getAccessTokenEndpoint()); + OAuthRequest request = new OAuthRequest(api.getAccessTokenVerb(), api.getAccessTokenEndpoint()); + request.addOAuthParameter(OAuthConstants.TOKEN, requestToken.getToken()); + request.addOAuthParameter(OAuthConstants.VERIFIER, verifier.getValue()); + + config.log("setting token to: " + requestToken + " and verifier to: " + verifier); + addOAuthParams(request, requestToken); + appendSignature(request); + + config.log("sending request..."); + Response response = request.send(tuner); + String body = response.getBody(); + + config.log("response status code: " + response.getCode()); + config.log("response body: " + body); + return api.getAccessTokenExtractor().extract(body); + } + + /** + * {@inheritDoc} + */ + public void signRequest(Token token, OAuthRequest request) + { + config.log("signing request: " + request.getCompleteUrl()); + + // Do not append the token if empty. This is for two legged OAuth calls. + if (!token.isEmpty()) + { + request.addOAuthParameter(OAuthConstants.TOKEN, token.getToken()); + } + config.log("setting token to: " + token); + addOAuthParams(request, token); + appendSignature(request); + } + + /** + * {@inheritDoc} + */ + public String getVersion() + { + return VERSION; + } + + /** + * {@inheritDoc} + */ + public String getAuthorizationUrl(Token requestToken) + { + return api.getAuthorizationUrl(requestToken); + } + + private String getSignature(OAuthRequest request, Token token) + { + config.log("generating signature..."); + config.log("using base64 encoder: " + Base64Encoder.type()); + String baseString = api.getBaseStringExtractor().extract(request); + String signature = api.getSignatureService().getSignature(baseString, config.getApiSecret(), token.getSecret()); + + config.log("base string is: " + baseString); + config.log("signature is: " + signature); + return signature; + } + + private void appendSignature(OAuthRequest request) + { + switch (config.getSignatureType()) + { + case Header: + config.log("using Http Header signature"); + + String oauthHeader = api.getHeaderExtractor().extract(request); + request.addHeader(OAuthConstants.HEADER, oauthHeader); + break; + case QueryString: + config.log("using Querystring signature"); + + for (Map.Entry entry : request.getOauthParameters().entrySet()) + { + request.addQuerystringParameter(entry.getKey(), entry.getValue()); + } + break; + } + } + + private static class TimeoutTuner extends RequestTuner + { + private final int duration; + private final TimeUnit unit; + + public TimeoutTuner(int duration, TimeUnit unit) + { + this.duration = duration; + this.unit = unit; + } + + @Override + public void tune(Request request) + { + request.setReadTimeout(duration, unit); + } + } +} diff --git a/src/main/resources/scribe-java-project/src/main/java/org/scribe/oauth/OAuth20ServiceImpl.java b/src/main/resources/scribe-java-project/src/main/java/org/scribe/oauth/OAuth20ServiceImpl.java new file mode 100644 index 0000000..6262c37 --- /dev/null +++ b/src/main/resources/scribe-java-project/src/main/java/org/scribe/oauth/OAuth20ServiceImpl.java @@ -0,0 +1,72 @@ +package org.scribe.oauth; + +import org.scribe.builder.api.*; +import org.scribe.model.*; + +public class OAuth20ServiceImpl implements OAuthService +{ + private static final String VERSION = "2.0"; + + private final DefaultApi20 api; + private final OAuthConfig config; + + /** + * Default constructor + * + * @param api OAuth2.0 api information + * @param config OAuth 2.0 configuration param object + */ + public OAuth20ServiceImpl(DefaultApi20 api, OAuthConfig config) + { + this.api = api; + this.config = config; + } + + /** + * {@inheritDoc} + */ + public Token getAccessToken(Token requestToken, Verifier verifier) + { + OAuthRequest request = new OAuthRequest(api.getAccessTokenVerb(), api.getAccessTokenEndpoint()); + request.addQuerystringParameter(OAuthConstants.CLIENT_ID, config.getApiKey()); + request.addQuerystringParameter(OAuthConstants.CLIENT_SECRET, config.getApiSecret()); + request.addQuerystringParameter(OAuthConstants.CODE, verifier.getValue()); + request.addQuerystringParameter(OAuthConstants.REDIRECT_URI, config.getCallback()); + if(config.hasScope()) request.addQuerystringParameter(OAuthConstants.SCOPE, config.getScope()); + Response response = request.send(); + return api.getAccessTokenExtractor().extract(response.getBody()); + } + + /** + * {@inheritDoc} + */ + public Token getRequestToken() + { + throw new UnsupportedOperationException("Unsupported operation, please use 'getAuthorizationUrl' and redirect your users there"); + } + + /** + * {@inheritDoc} + */ + public String getVersion() + { + return VERSION; + } + + /** + * {@inheritDoc} + */ + public void signRequest(Token accessToken, OAuthRequest request) + { + request.addQuerystringParameter(OAuthConstants.ACCESS_TOKEN, accessToken.getToken()); + } + + /** + * {@inheritDoc} + */ + public String getAuthorizationUrl(Token requestToken) + { + return api.getAuthorizationUrl(config); + } + +} diff --git a/src/main/resources/scribe-java-project/src/main/java/org/scribe/oauth/OAuthService.java b/src/main/resources/scribe-java-project/src/main/java/org/scribe/oauth/OAuthService.java new file mode 100644 index 0000000..0c9c57e --- /dev/null +++ b/src/main/resources/scribe-java-project/src/main/java/org/scribe/oauth/OAuthService.java @@ -0,0 +1,53 @@ +package org.scribe.oauth; + +import org.scribe.model.*; + +/** + * The main Scribe object. + * + * A facade responsible for the retrieval of request and access tokens and for the signing of HTTP requests. + * + * @author Pablo Fernandez + */ +public interface OAuthService +{ + /** + * Retrieve the request token. + * + * @return request token + */ + public Token getRequestToken(); + + /** + * Retrieve the access token + * + * @param requestToken request token (obtained previously) + * @param verifier verifier code + * @return access token + */ + public Token getAccessToken(Token requestToken, Verifier verifier); + + /** + * Signs am OAuth request + * + * @param accessToken access token (obtained previously) + * @param request request to sign + */ + public void signRequest(Token accessToken, OAuthRequest request); + + /** + * Returns the OAuth version of the service. + * + * @return oauth version as string + */ + public String getVersion(); + + /** + * Returns the URL where you should redirect your users to authenticate + * your application. + * + * @param requestToken the request token you need to authorize + * @return the URL where you should redirect your users + */ + public String getAuthorizationUrl(Token requestToken); +} diff --git a/src/main/resources/scribe-java-project/src/main/java/org/scribe/services/Base64Encoder.java b/src/main/resources/scribe-java-project/src/main/java/org/scribe/services/Base64Encoder.java new file mode 100644 index 0000000..4a091c1 --- /dev/null +++ b/src/main/resources/scribe-java-project/src/main/java/org/scribe/services/Base64Encoder.java @@ -0,0 +1,36 @@ +package org.scribe.services; + +public abstract class Base64Encoder +{ + private static Base64Encoder instance; + + public static synchronized Base64Encoder getInstance() + { + if (instance == null) + { + instance = createEncoderInstance(); + } + return instance; + } + + private static Base64Encoder createEncoderInstance() + { + if (CommonsEncoder.isPresent()) + { + return new CommonsEncoder(); + } + else + { + return new DatatypeConverterEncoder(); + } + } + + public static String type() + { + return getInstance().getType(); + } + + public abstract String encode(byte[] bytes); + + public abstract String getType(); +} diff --git a/src/main/resources/scribe-java-project/src/main/java/org/scribe/services/CommonsEncoder.java b/src/main/resources/scribe-java-project/src/main/java/org/scribe/services/CommonsEncoder.java new file mode 100644 index 0000000..4269a69 --- /dev/null +++ b/src/main/resources/scribe-java-project/src/main/java/org/scribe/services/CommonsEncoder.java @@ -0,0 +1,42 @@ +package org.scribe.services; + +import org.apache.commons.codec.binary.*; +import org.scribe.exceptions.*; + +import java.io.UnsupportedEncodingException; + +public class CommonsEncoder extends Base64Encoder +{ + + @Override + public String encode(byte[] bytes) + { + try + { + return new String(Base64.encodeBase64(bytes), "UTF-8"); + } + catch (UnsupportedEncodingException e) + { + throw new OAuthSignatureException("Can't perform base64 encoding", e); + } + } + + @Override + public String getType() + { + return "CommonsCodec"; + } + + public static boolean isPresent() + { + try + { + Class.forName("org.apache.commons.codec.binary.Base64"); + return true; + } + catch (ClassNotFoundException e) + { + return false; + } + } +} diff --git a/src/main/resources/scribe-java-project/src/main/java/org/scribe/services/DatatypeConverterEncoder.java b/src/main/resources/scribe-java-project/src/main/java/org/scribe/services/DatatypeConverterEncoder.java new file mode 100644 index 0000000..d147eba --- /dev/null +++ b/src/main/resources/scribe-java-project/src/main/java/org/scribe/services/DatatypeConverterEncoder.java @@ -0,0 +1,18 @@ +package org.scribe.services; + +import javax.xml.bind.*; + +public class DatatypeConverterEncoder extends Base64Encoder +{ + @Override + public String encode(byte[] bytes) + { + return DatatypeConverter.printBase64Binary(bytes); + } + + @Override + public String getType() + { + return "DatatypeConverter"; + } +} diff --git a/src/main/resources/scribe-java-project/src/main/java/org/scribe/services/HMACSha1SignatureService.java b/src/main/resources/scribe-java-project/src/main/java/org/scribe/services/HMACSha1SignatureService.java new file mode 100644 index 0000000..560c2e6 --- /dev/null +++ b/src/main/resources/scribe-java-project/src/main/java/org/scribe/services/HMACSha1SignatureService.java @@ -0,0 +1,61 @@ +package org.scribe.services; + +import javax.crypto.*; +import javax.crypto.spec.*; + +import org.scribe.exceptions.*; +import org.scribe.utils.*; + +/** + * HMAC-SHA1 implementation of {@SignatureService} + * + * @author Pablo Fernandez + * + */ +public class HMACSha1SignatureService implements SignatureService +{ + private static final String EMPTY_STRING = ""; + private static final String CARRIAGE_RETURN = "\r\n"; + private static final String UTF8 = "UTF-8"; + private static final String HMAC_SHA1 = "HmacSHA1"; + private static final String METHOD = "HMAC-SHA1"; + + /** + * {@inheritDoc} + */ + public String getSignature(String baseString, String apiSecret, String tokenSecret) + { + try + { + Preconditions.checkEmptyString(baseString, "Base string cant be null or empty string"); + Preconditions.checkEmptyString(apiSecret, "Api secret cant be null or empty string"); + return doSign(baseString, OAuthEncoder.encode(apiSecret) + '&' + OAuthEncoder.encode(tokenSecret)); + } + catch (Exception e) + { + throw new OAuthSignatureException(baseString, e); + } + } + + private String doSign(String toSign, String keyString) throws Exception + { + SecretKeySpec key = new SecretKeySpec((keyString).getBytes(UTF8), HMAC_SHA1); + Mac mac = Mac.getInstance(HMAC_SHA1); + mac.init(key); + byte[] bytes = mac.doFinal(toSign.getBytes(UTF8)); + return bytesToBase64String(bytes).replace(CARRIAGE_RETURN, EMPTY_STRING); + } + + private String bytesToBase64String(byte[] bytes) + { + return Base64Encoder.getInstance().encode(bytes); + } + + /** + * {@inheritDoc} + */ + public String getSignatureMethod() + { + return METHOD; + } +} diff --git a/src/main/resources/scribe-java-project/src/main/java/org/scribe/services/PlaintextSignatureService.java b/src/main/resources/scribe-java-project/src/main/java/org/scribe/services/PlaintextSignatureService.java new file mode 100644 index 0000000..03306e8 --- /dev/null +++ b/src/main/resources/scribe-java-project/src/main/java/org/scribe/services/PlaintextSignatureService.java @@ -0,0 +1,40 @@ +package org.scribe.services; + +import org.scribe.exceptions.*; +import org.scribe.utils.*; + +/** + * plaintext implementation of {@SignatureService} + * + * @author Pablo Fernandez + * + */ +public class PlaintextSignatureService implements SignatureService +{ + private static final String METHOD = "PLAINTEXT"; + + /** + * {@inheritDoc} + */ + public String getSignature(String baseString, String apiSecret, String tokenSecret) + { + try + { + Preconditions.checkEmptyString(apiSecret, "Api secret cant be null or empty string"); + return OAuthEncoder.encode(apiSecret) + '&' + OAuthEncoder.encode(tokenSecret); + } + catch (Exception e) + { + throw new OAuthSignatureException(baseString, e); + } + } + + /** + * {@inheritDoc} + */ + public String getSignatureMethod() + { + return METHOD; + } +} + diff --git a/src/main/resources/scribe-java-project/src/main/java/org/scribe/services/RSASha1SignatureService.java b/src/main/resources/scribe-java-project/src/main/java/org/scribe/services/RSASha1SignatureService.java new file mode 100644 index 0000000..c427611 --- /dev/null +++ b/src/main/resources/scribe-java-project/src/main/java/org/scribe/services/RSASha1SignatureService.java @@ -0,0 +1,52 @@ +package org.scribe.services; + +import org.scribe.exceptions.*; +import java.security.*; + +/** + * A signature service that uses the RSA-SHA1 algorithm. + */ +public class RSASha1SignatureService implements SignatureService +{ + private static final String METHOD = "RSA-SHA1"; + private static final String RSA_SHA1 = "SHA1withRSA"; + private static final String UTF8 = "UTF-8"; + + private PrivateKey privateKey; + + public RSASha1SignatureService(PrivateKey privateKey) + { + this.privateKey = privateKey; + } + + /** + * {@inheritDoc} + */ + public String getSignature(String baseString, String apiSecret, String tokenSecret) + { + try + { + Signature signature = Signature.getInstance(RSA_SHA1); + signature.initSign(privateKey); + signature.update(baseString.getBytes(UTF8)); + return bytesToBase64String(signature); + } + catch (Exception e) + { + throw new OAuthSignatureException(baseString, e); + } + } + + private String bytesToBase64String(Signature signature) throws SignatureException + { + return Base64Encoder.getInstance().encode(signature.sign()); + } + + /** + * {@inheritDoc} + */ + public String getSignatureMethod() + { + return METHOD; + } +} \ No newline at end of file diff --git a/src/main/resources/scribe-java-project/src/main/java/org/scribe/services/SignatureService.java b/src/main/resources/scribe-java-project/src/main/java/org/scribe/services/SignatureService.java new file mode 100644 index 0000000..229c2f6 --- /dev/null +++ b/src/main/resources/scribe-java-project/src/main/java/org/scribe/services/SignatureService.java @@ -0,0 +1,28 @@ +package org.scribe.services; + +/** + * Signs a base string, returning the OAuth signature + * + * @author Pablo Fernandez + * + */ +public interface SignatureService +{ + /** + * Returns the signature + * + * @param baseString url-encoded string to sign + * @param apiSecret api secret for your app + * @param tokenSecret token secret (empty string for the request token step) + * + * @return signature + */ + public String getSignature(String baseString, String apiSecret, String tokenSecret); + + /** + * Returns the signature method/algorithm + * + * @return + */ + public String getSignatureMethod(); +} diff --git a/src/main/resources/scribe-java-project/src/main/java/org/scribe/services/TimestampService.java b/src/main/resources/scribe-java-project/src/main/java/org/scribe/services/TimestampService.java new file mode 100644 index 0000000..221a226 --- /dev/null +++ b/src/main/resources/scribe-java-project/src/main/java/org/scribe/services/TimestampService.java @@ -0,0 +1,25 @@ +package org.scribe.services; + +/** + * Unix epoch timestamp generator. + * + * This class is useful for stubbing in tests. + * + * @author Pablo Fernandez + */ +public interface TimestampService +{ + /** + * Returns the unix epoch timestamp in seconds + * + * @return timestamp + */ + public String getTimestampInSeconds(); + + /** + * Returns a nonce (unique value for each request) + * + * @return nonce + */ + public String getNonce(); +} diff --git a/src/main/resources/scribe-java-project/src/main/java/org/scribe/services/TimestampServiceImpl.java b/src/main/resources/scribe-java-project/src/main/java/org/scribe/services/TimestampServiceImpl.java new file mode 100644 index 0000000..486e93c --- /dev/null +++ b/src/main/resources/scribe-java-project/src/main/java/org/scribe/services/TimestampServiceImpl.java @@ -0,0 +1,68 @@ +package org.scribe.services; + +import java.util.*; + +/** + * Implementation of {@link TimestampService} using plain java classes. + * + * @author Pablo Fernandez + */ +public class TimestampServiceImpl implements TimestampService +{ + private Timer timer; + + /** + * Default constructor. + */ + public TimestampServiceImpl() + { + timer = new Timer(); + } + + /** + * {@inheritDoc} + */ + public String getNonce() + { + Long ts = getTs(); + return String.valueOf(ts + timer.getRandomInteger()); + } + + /** + * {@inheritDoc} + */ + public String getTimestampInSeconds() + { + return String.valueOf(getTs()); + } + + private Long getTs() + { + return timer.getMilis() / 1000; + } + + void setTimer(Timer timer) + { + this.timer = timer; + } + + /** + * Inner class that uses {@link System} for generating the timestamps. + * + * @author Pablo Fernandez + */ + static class Timer + { + private final Random rand = new Random(); + Long getMilis() + { + return System.currentTimeMillis(); + } + + Integer getRandomInteger() + { + return rand.nextInt(); + } + } + +} diff --git a/src/main/resources/scribe-java-project/src/main/java/org/scribe/utils/MapUtils.java b/src/main/resources/scribe-java-project/src/main/java/org/scribe/utils/MapUtils.java new file mode 100644 index 0000000..ee09d16 --- /dev/null +++ b/src/main/resources/scribe-java-project/src/main/java/org/scribe/utils/MapUtils.java @@ -0,0 +1,24 @@ +package org.scribe.utils; + +import java.util.Map; + +/** + * @author: Pablo Fernandez + */ +public class MapUtils +{ + private MapUtils(){} + + public static String toString(Map map) + { + if (map == null) return ""; + if (map.isEmpty()) return "{}"; + + StringBuilder result = new StringBuilder(); + for(Map.Entry entry : map.entrySet()) + { + result.append(String.format(", %s -> %s ", entry.getKey().toString(), entry.getValue().toString())); + } + return "{" + result.substring(1) + "}"; + } +} diff --git a/src/main/resources/scribe-java-project/src/main/java/org/scribe/utils/OAuthEncoder.java b/src/main/resources/scribe-java-project/src/main/java/org/scribe/utils/OAuthEncoder.java new file mode 100644 index 0000000..7fdbc84 --- /dev/null +++ b/src/main/resources/scribe-java-project/src/main/java/org/scribe/utils/OAuthEncoder.java @@ -0,0 +1,64 @@ +package org.scribe.utils; + +import java.io.*; +import java.net.*; +import java.util.*; +import java.util.regex.*; +import org.scribe.exceptions.*; + +/** + * @author: Pablo Fernandez + */ +public class OAuthEncoder +{ + private static String CHARSET = "UTF-8"; + private static final Map ENCODING_RULES; + + static + { + Map rules = new HashMap(); + rules.put("*", "%2A"); + rules.put("+", "%20"); + rules.put("%7E", "~"); + ENCODING_RULES = Collections.unmodifiableMap(rules); + } + + private OAuthEncoder(){} + + public static String encode(String plain) + { + Preconditions.checkNotNull(plain, "Cannot encode null object"); + String encoded = ""; + try + { + encoded = URLEncoder.encode(plain, CHARSET); + } + catch (UnsupportedEncodingException uee) + { + throw new OAuthException("Charset not found while encoding string: " + CHARSET, uee); + } + for(Map.Entry rule : ENCODING_RULES.entrySet()) + { + encoded = applyRule(encoded, rule.getKey(), rule.getValue()); + } + return encoded; + } + + private static String applyRule(String encoded, String toReplace, String replacement) + { + return encoded.replaceAll(Pattern.quote(toReplace), replacement); + } + + public static String decode(String encoded) + { + Preconditions.checkNotNull(encoded, "Cannot decode null object"); + try + { + return URLDecoder.decode(encoded, CHARSET); + } + catch(UnsupportedEncodingException uee) + { + throw new OAuthException("Charset not found while decoding string: " + CHARSET, uee); + } + } +} diff --git a/src/main/resources/scribe-java-project/src/main/java/org/scribe/utils/Preconditions.java b/src/main/resources/scribe-java-project/src/main/java/org/scribe/utils/Preconditions.java new file mode 100644 index 0000000..f6e5b15 --- /dev/null +++ b/src/main/resources/scribe-java-project/src/main/java/org/scribe/utils/Preconditions.java @@ -0,0 +1,88 @@ +package org.scribe.utils; + +import java.util.regex.Pattern; + +import org.scribe.model.OAuthConstants; + +/** + * Utils for checking preconditions and invariants + * + * @author Pablo Fernandez + */ +public class Preconditions +{ + private static final String DEFAULT_MESSAGE = "Received an invalid parameter"; + + // scheme = alpha *( alpha | digit | "+" | "-" | "." ) + private static final Pattern URL_PATTERN = Pattern.compile("^[a-zA-Z][a-zA-Z0-9+.-]*://\\S+"); + + private Preconditions(){} + + /** + * Checks that an object is not null. + * + * @param object any object + * @param errorMsg error message + * + * @throws IllegalArgumentException if the object is null + */ + public static void checkNotNull(Object object, String errorMsg) + { + check(object != null, errorMsg); + } + + /** + * Checks that a string is not null or empty + * + * @param string any string + * @param errorMsg error message + * + * @throws IllegalArgumentException if the string is null or empty + */ + public static void checkEmptyString(String string, String errorMsg) + { + check(string != null && !string.trim().equals(""), errorMsg); + } + + /** + * Checks that a URL is valid + * + * @param url any string + * @param errorMsg error message + */ + public static void checkValidUrl(String url, String errorMsg) + { + checkEmptyString(url, errorMsg); + check(isUrl(url), errorMsg); + } + + /** + * Checks that a URL is a valid OAuth callback + * + * @param url any string + * @param errorMsg error message + */ + public static void checkValidOAuthCallback(String url, String errorMsg) + { + checkEmptyString(url, errorMsg); + if(url.compareToIgnoreCase(OAuthConstants.OUT_OF_BAND) != 0) + { + check(isUrl(url), errorMsg); + } + } + + private static boolean isUrl(String url) + { + return URL_PATTERN.matcher(url).matches(); + } + + private static void check(boolean requirements, String error) + { + String message = (error == null || error.trim().length() <= 0) ? DEFAULT_MESSAGE : error; + if (!requirements) + { + throw new IllegalArgumentException(message); + } + } + +} diff --git a/src/main/resources/scribe-java-project/src/main/java/org/scribe/utils/StreamUtils.java b/src/main/resources/scribe-java-project/src/main/java/org/scribe/utils/StreamUtils.java new file mode 100644 index 0000000..30dd8bc --- /dev/null +++ b/src/main/resources/scribe-java-project/src/main/java/org/scribe/utils/StreamUtils.java @@ -0,0 +1,44 @@ +package org.scribe.utils; + +import java.io.*; + +/** + * Utils to deal with Streams. + * + * @author Pablo Fernandez + */ +public class StreamUtils +{ + private StreamUtils(){} + + /** + * Returns the stream contents as an UTF-8 encoded string + * + * @param is input stream + * @return string contents + */ + public static String getStreamContents(InputStream is) + { + Preconditions.checkNotNull(is, "Cannot get String from a null object"); + try + { + final char[] buffer = new char[0x10000]; + StringBuilder out = new StringBuilder(); + Reader in = new InputStreamReader(is, "UTF-8"); + int read; + do + { + read = in.read(buffer, 0, buffer.length); + if (read > 0) + { + out.append(buffer, 0, read); + } + } while (read >= 0); + in.close(); + return out.toString(); + } catch (IOException ioe) + { + throw new IllegalStateException("Error while reading response body", ioe); + } + } +} diff --git a/src/main/resources/scribe-java-project/src/test/java/org/scribe/builder/ServiceBuilderTest.java b/src/main/resources/scribe-java-project/src/test/java/org/scribe/builder/ServiceBuilderTest.java new file mode 100644 index 0000000..8112d79 --- /dev/null +++ b/src/main/resources/scribe-java-project/src/test/java/org/scribe/builder/ServiceBuilderTest.java @@ -0,0 +1,73 @@ +package org.scribe.builder; + +import static org.junit.Assert.*; + +import org.junit.*; +import org.scribe.builder.api.*; +import org.scribe.model.*; +import org.scribe.oauth.*; + +public class ServiceBuilderTest +{ + private ServiceBuilder builder; + + @Before + public void setup() + { + builder = new ServiceBuilder(); + } + + @Test + public void shouldReturnConfigDefaultValues() + { + builder.provider(ApiMock.class).apiKey("key").apiSecret("secret").build(); + assertEquals(ApiMock.config.getApiKey(), "key"); + assertEquals(ApiMock.config.getApiSecret(), "secret"); + assertEquals(ApiMock.config.getCallback(), OAuthConstants.OUT_OF_BAND); + assertEquals(ApiMock.config.getSignatureType(), SignatureType.Header); + } + + @Test + public void shouldAcceptValidCallbackUrl() + { + builder.provider(ApiMock.class).apiKey("key").apiSecret("secret").callback("http://example.com").build(); + assertEquals(ApiMock.config.getApiKey(), "key"); + assertEquals(ApiMock.config.getApiSecret(), "secret"); + assertEquals(ApiMock.config.getCallback(), "http://example.com"); + } + + @Test + public void shouldAcceptASignatureType() + { + builder.provider(ApiMock.class).apiKey("key").apiSecret("secret").signatureType(SignatureType.QueryString).build(); + assertEquals(ApiMock.config.getApiKey(), "key"); + assertEquals(ApiMock.config.getApiSecret(), "secret"); + assertEquals(ApiMock.config.getSignatureType(), SignatureType.QueryString); + } + + @Test(expected=IllegalArgumentException.class) + public void shouldNotAcceptNullAsCallback() + { + builder.provider(ApiMock.class).apiKey("key").apiSecret("secret").callback(null).build(); + } + + @Test + public void shouldAcceptAnScope() + { + builder.provider(ApiMock.class).apiKey("key").apiSecret("secret").scope("rss-api").build(); + assertEquals(ApiMock.config.getApiKey(), "key"); + assertEquals(ApiMock.config.getApiSecret(), "secret"); + assertEquals(ApiMock.config.getScope(), "rss-api"); + } + + public static class ApiMock implements Api + { + public static OAuthConfig config; + + public OAuthService createService(OAuthConfig config) + { + ApiMock.config = config; + return null; + } + } +} diff --git a/src/main/resources/scribe-java-project/src/test/java/org/scribe/examples/AWeberExample.java b/src/main/resources/scribe-java-project/src/test/java/org/scribe/examples/AWeberExample.java new file mode 100644 index 0000000..2d86d61 --- /dev/null +++ b/src/main/resources/scribe-java-project/src/test/java/org/scribe/examples/AWeberExample.java @@ -0,0 +1,65 @@ +package org.scribe.examples; + +import java.util.Scanner; + +import org.scribe.builder.*; +import org.scribe.builder.api.*; +import org.scribe.model.*; +import org.scribe.oauth.*; + +public class AWeberExample +{ + + //To get your consumer key/secret, and view API docs, see https://labs.aweber.com/docs + private static final String ACCOUNT_RESOURCE_URL = "https://api.aweber.com/1.0/accounts/"; + + private static final String CONSUMER_KEY = ""; + private static final String CONSUMER_SECRET = ""; + + public static void main(String[] args) + { + OAuthService service = new ServiceBuilder() + .provider(AWeberApi.class) + .apiKey(CONSUMER_KEY) + .apiSecret(CONSUMER_SECRET) + .build(); + + Scanner in = new Scanner(System.in); + + System.out.println("=== AWeber's OAuth Workflow ==="); + System.out.println(); + + // Obtain the Request Token + System.out.println("Fetching the Request Token..."); + Token requestToken = service.getRequestToken(); + System.out.println("Got the Request Token!"); + System.out.println(); + + System.out.println("Now go and authorize Scribe here:"); + System.out.println(service.getAuthorizationUrl(requestToken)); + System.out.println("And paste the verifier here"); + System.out.print(">>"); + Verifier verifier = new Verifier(in.nextLine()); + System.out.println(); + + // Trade the Request Token and Verfier for the Access Token + System.out.println("Trading the Request Token for an Access Token..."); + Token accessToken = service.getAccessToken(requestToken, verifier); + System.out.println("Got the Access Token!"); + System.out.println("(if your curious it looks like this: " + accessToken + " )"); + System.out.println(); + + // Now let's go and ask for a protected resource! + System.out.println("Now we're going to access a protected resource..."); + OAuthRequest request = new OAuthRequest(Verb.GET, ACCOUNT_RESOURCE_URL); + service.signRequest(accessToken, request); + Response response = request.send(); + System.out.println("Got it! Lets see what we found..."); + System.out.println(); + System.out.println(response.getBody()); + + System.out.println(); + System.out.println("Thats it man! Go and build something awesome with AWeber and Scribe! :)"); + } + +} \ No newline at end of file diff --git a/src/main/resources/scribe-java-project/src/test/java/org/scribe/examples/DiggExample.java b/src/main/resources/scribe-java-project/src/test/java/org/scribe/examples/DiggExample.java new file mode 100644 index 0000000..63fea8b --- /dev/null +++ b/src/main/resources/scribe-java-project/src/test/java/org/scribe/examples/DiggExample.java @@ -0,0 +1,65 @@ +package org.scribe.examples; + +import java.util.*; + +import org.scribe.builder.*; +import org.scribe.builder.api.*; +import org.scribe.model.*; +import org.scribe.oauth.*; + +public class DiggExample +{ + private static final String NETWORK_NAME = "Digg"; + private static final String PROTECTED_RESOURCE_URL = "http://services.digg.com/2.0/comment.digg"; + + public static void main(String[] args) + { + // Replace these with your own api key and secret + String apiKey = "myKey"; + String apiSecret = "mySecret"; + OAuthService service = new ServiceBuilder().provider(DiggApi.class).apiKey(apiKey).apiSecret(apiSecret).build(); + Scanner in = new Scanner(System.in); + + System.out.println("=== " + NETWORK_NAME + "'s OAuth Workflow ==="); + System.out.println(); + + // Obtain the Request Token + System.out.println("Fetching the Request Token..."); + Token requestToken = service.getRequestToken(); + System.out.println("Got the Request Token!"); + System.out.println(); + + // Obtain the Authorization URL + System.out.println("Fetching the Authorization URL..."); + String authorizationUrl = service.getAuthorizationUrl(requestToken); + System.out.println("Got the Authorization URL!"); + System.out.println("Now go and authorize Scribe here:"); + System.out.println(authorizationUrl); + System.out.println("And paste the authorization code here"); + System.out.print(">>"); + Verifier verifier = new Verifier(in.nextLine()); + System.out.println(); + + // Trade the Request Token and Verfier for the Access Token + System.out.println("Trading the Request Token for an Access Token..."); + Token accessToken = service.getAccessToken(requestToken, verifier); + System.out.println("Got the Access Token!"); + System.out.println("(if your curious it looks like this: " + accessToken + " )"); + System.out.println(); + + // Now let's go and ask for a protected resource! + System.out.println("Now we're going to access a protected resource..."); + OAuthRequest request = new OAuthRequest(Verb.POST, PROTECTED_RESOURCE_URL); + request.addBodyParameter("comment_id", "20100729223726:4fef610331ee46a3b5cbd740bf71313e"); + service.signRequest(accessToken, request); + Response response = request.send(); + System.out.println("Got it! Lets see what we found..."); + System.out.println(); + System.out.println(response.getCode()); + System.out.println(response.getBody()); + + System.out.println(); + System.out.println("Thats it man! Go and build something awesome with Scribe! :)"); + + } +} \ No newline at end of file diff --git a/src/main/resources/scribe-java-project/src/test/java/org/scribe/examples/FacebookExample.java b/src/main/resources/scribe-java-project/src/test/java/org/scribe/examples/FacebookExample.java new file mode 100644 index 0000000..d5dc3cb --- /dev/null +++ b/src/main/resources/scribe-java-project/src/test/java/org/scribe/examples/FacebookExample.java @@ -0,0 +1,64 @@ +package org.scribe.examples; + +import java.util.*; + +import org.scribe.builder.*; +import org.scribe.builder.api.*; +import org.scribe.model.*; +import org.scribe.oauth.*; + +public class FacebookExample +{ + private static final String NETWORK_NAME = "Facebook"; + private static final String PROTECTED_RESOURCE_URL = "https://graph.facebook.com/me"; + private static final Token EMPTY_TOKEN = null; + + public static void main(String[] args) + { + // Replace these with your own api key and secret + String apiKey = "your_app_id"; + String apiSecret = "your_api_secret"; + OAuthService service = new ServiceBuilder() + .provider(FacebookApi.class) + .apiKey(apiKey) + .apiSecret(apiSecret) + .callback("http://www.example.com/oauth_callback/") + .build(); + Scanner in = new Scanner(System.in); + + System.out.println("=== " + NETWORK_NAME + "'s OAuth Workflow ==="); + System.out.println(); + + // Obtain the Authorization URL + System.out.println("Fetching the Authorization URL..."); + String authorizationUrl = service.getAuthorizationUrl(EMPTY_TOKEN); + System.out.println("Got the Authorization URL!"); + System.out.println("Now go and authorize Scribe here:"); + System.out.println(authorizationUrl); + System.out.println("And paste the authorization code here"); + System.out.print(">>"); + Verifier verifier = new Verifier(in.nextLine()); + System.out.println(); + + // Trade the Request Token and Verfier for the Access Token + System.out.println("Trading the Request Token for an Access Token..."); + Token accessToken = service.getAccessToken(EMPTY_TOKEN, verifier); + System.out.println("Got the Access Token!"); + System.out.println("(if your curious it looks like this: " + accessToken + " )"); + System.out.println(); + + // Now let's go and ask for a protected resource! + System.out.println("Now we're going to access a protected resource..."); + OAuthRequest request = new OAuthRequest(Verb.GET, PROTECTED_RESOURCE_URL); + service.signRequest(accessToken, request); + Response response = request.send(); + System.out.println("Got it! Lets see what we found..."); + System.out.println(); + System.out.println(response.getCode()); + System.out.println(response.getBody()); + + System.out.println(); + System.out.println("Thats it man! Go and build something awesome with Scribe! :)"); + + } +} \ No newline at end of file diff --git a/src/main/resources/scribe-java-project/src/test/java/org/scribe/examples/FlickrExample.java b/src/main/resources/scribe-java-project/src/test/java/org/scribe/examples/FlickrExample.java new file mode 100644 index 0000000..ac38ad3 --- /dev/null +++ b/src/main/resources/scribe-java-project/src/test/java/org/scribe/examples/FlickrExample.java @@ -0,0 +1,59 @@ +package org.scribe.examples; + +import org.scribe.builder.*; +import org.scribe.builder.api.*; +import org.scribe.model.*; +import org.scribe.oauth.*; + +import java.util.*; + +public class FlickrExample +{ + private static final String PROTECTED_RESOURCE_URL = "http://api.flickr.com/services/rest/"; + + public static void main(String[] args) + { + // Replace these with your own api key and secret + String apiKey = "your_app_id"; + String apiSecret = "your_api_secret"; + OAuthService service = new ServiceBuilder().provider(FlickrApi.class).apiKey(apiKey).apiSecret(apiSecret).build(); + Scanner in = new Scanner(System.in); + + System.out.println("=== Flickr's OAuth Workflow ==="); + System.out.println(); + + // Obtain the Request Token + System.out.println("Fetching the Request Token..."); + Token requestToken = service.getRequestToken(); + System.out.println("Got the Request Token!"); + System.out.println(); + + System.out.println("Now go and authorize Scribe here:"); + String authorizationUrl = service.getAuthorizationUrl(requestToken); + System.out.println(authorizationUrl + "&perms=read"); + System.out.println("And paste the verifier here"); + System.out.print(">>"); + Verifier verifier = new Verifier(in.nextLine()); + System.out.println(); + + // Trade the Request Token and Verfier for the Access Token + System.out.println("Trading the Request Token for an Access Token..."); + Token accessToken = service.getAccessToken(requestToken, verifier); + System.out.println("Got the Access Token!"); + System.out.println("(if your curious it looks like this: " + accessToken + " )"); + System.out.println(); + + // Now let's go and ask for a protected resource! + System.out.println("Now we're going to access a protected resource..."); + OAuthRequest request = new OAuthRequest(Verb.GET, PROTECTED_RESOURCE_URL); + request.addQuerystringParameter("method", "flickr.test.login"); + service.signRequest(accessToken, request); + Response response = request.send(); + System.out.println("Got it! Lets see what we found..."); + System.out.println(); + System.out.println(response.getBody()); + + System.out.println(); + System.out.println("Thats it man! Go and build something awesome with Scribe! :)"); + } +} diff --git a/src/main/resources/scribe-java-project/src/test/java/org/scribe/examples/Foursquare2Example.java b/src/main/resources/scribe-java-project/src/test/java/org/scribe/examples/Foursquare2Example.java new file mode 100644 index 0000000..35495a8 --- /dev/null +++ b/src/main/resources/scribe-java-project/src/test/java/org/scribe/examples/Foursquare2Example.java @@ -0,0 +1,63 @@ +package org.scribe.examples; + +import java.util.*; + +import org.scribe.builder.*; +import org.scribe.builder.api.*; +import org.scribe.model.*; +import org.scribe.oauth.*; + +public class Foursquare2Example +{ + private static final String PROTECTED_RESOURCE_URL = "https://api.foursquare.com/v2/users/self/friends?oauth_token="; + private static final Token EMPTY_TOKEN = null; + + public static void main(String[] args) + { + // Replace these with your own api key and secret + String apiKey = "FEGFXJUFANVVDHVSNUAMUKTTXCP1AJQD53E33XKJ44YP1S4I"; + String apiSecret = "AYWKUL5SWPNC0CTQ202QXRUG2NLZYXMRA34ZSDW4AUYBG2RC"; + OAuthService service = new ServiceBuilder() + .provider(Foursquare2Api.class) + .apiKey(apiKey) + .apiSecret(apiSecret) + .callback("http://localhost:9000/") + .build(); + Scanner in = new Scanner(System.in); + + System.out.println("=== Foursquare2's OAuth Workflow ==="); + System.out.println(); + + // Obtain the Authorization URL + System.out.println("Fetching the Authorization URL..."); + String authorizationUrl = service.getAuthorizationUrl(EMPTY_TOKEN); + System.out.println("Got the Authorization URL!"); + System.out.println("Now go and authorize Scribe here:"); + System.out.println(authorizationUrl); + System.out.println("And paste the authorization code here"); + System.out.print(">>"); + Verifier verifier = new Verifier(in.nextLine()); + System.out.println(); + + // Trade the Request Token and Verfier for the Access Token + System.out.println("Trading the Request Token for an Access Token..."); + Token accessToken = service.getAccessToken(EMPTY_TOKEN, verifier); + System.out.println("Got the Access Token!"); + System.out.println("(if your curious it looks like this: " + accessToken + " )"); + System.out.println(); + + // Now let's go and ask for a protected resource! + System.out.println("Now we're going to access a protected resource..."); + OAuthRequest request = new OAuthRequest(Verb.GET, PROTECTED_RESOURCE_URL + accessToken.getToken()); + service.signRequest(accessToken, request); + Response response = request.send(); + System.out.println("Got it! Lets see what we found..."); + System.out.println(); + System.out.println(response.getCode()); + System.out.println(response.getBody()); + + System.out.println(); + System.out.println("Thats it man! Go and build something awesome with Scribe! :)"); + + } +} diff --git a/src/main/resources/scribe-java-project/src/test/java/org/scribe/examples/FoursquareExample.java b/src/main/resources/scribe-java-project/src/test/java/org/scribe/examples/FoursquareExample.java new file mode 100644 index 0000000..b227488 --- /dev/null +++ b/src/main/resources/scribe-java-project/src/test/java/org/scribe/examples/FoursquareExample.java @@ -0,0 +1,59 @@ +package org.scribe.examples; + +import java.util.Scanner; + +import org.scribe.builder.*; +import org.scribe.builder.api.*; +import org.scribe.model.*; +import org.scribe.oauth.*; + +public class FoursquareExample +{ + private static final String PROTECTED_RESOURCE_URL = "http://api.foursquare.com/v1/user"; + + public static void main(String[] args) + { + OAuthService service = new ServiceBuilder() + .provider(FoursquareApi.class) + .apiKey("FEGFXJUFANVVDHVSNUAMUKTTXCP1AJQD53E33XKJ44YP1S4I") + .apiSecret("AYWKUL5SWPNC0CTQ202QXRUG2NLZYXMRA34ZSDW4AUYBG2RC") + .build(); + Scanner in = new Scanner(System.in); + + System.out.println("=== Foursquare's OAuth Workflow ==="); + System.out.println(); + + // Obtain the Request Token + System.out.println("Fetching the Request Token..."); + Token requestToken = service.getRequestToken(); + System.out.println("Got the Request Token!"); + System.out.println(); + + System.out.println("Now go and authorize Scribe here:"); + System.out.println(service.getAuthorizationUrl(requestToken)); + System.out.println("And paste the verifier here"); + System.out.print(">>"); + Verifier verifier = new Verifier(in.nextLine()); + System.out.println(); + + // Trade the Request Token and Verfier for the Access Token + System.out.println("Trading the Request Token for an Access Token..."); + Token accessToken = service.getAccessToken(requestToken, verifier); + System.out.println("Got the Access Token!"); + System.out.println("(if your curious it looks like this: " + accessToken + " )"); + System.out.println(); + + // Now let's go and ask for a protected resource! + System.out.println("Now we're going to access a protected resource..."); + OAuthRequest request = new OAuthRequest(Verb.GET, PROTECTED_RESOURCE_URL); + service.signRequest(accessToken, request); + Response response = request.send(); + System.out.println("Got it! Lets see what we found..."); + System.out.println(); + System.out.println(response.getBody()); + + System.out.println(); + System.out.println("Thats it man! Go and build something awesome with Scribe! :)"); + } + +} \ No newline at end of file diff --git a/src/main/resources/scribe-java-project/src/test/java/org/scribe/examples/FreelancerExample.java b/src/main/resources/scribe-java-project/src/test/java/org/scribe/examples/FreelancerExample.java new file mode 100644 index 0000000..d1d5407 --- /dev/null +++ b/src/main/resources/scribe-java-project/src/test/java/org/scribe/examples/FreelancerExample.java @@ -0,0 +1,66 @@ +package org.scribe.examples; + +import java.util.*; +import org.scribe.builder.*; +import org.scribe.builder.api.*; +import org.scribe.model.*; +import org.scribe.oauth.*; + +public class FreelancerExample +{ + + private static final String NETWORK_NAME = "Freelancer"; + private static final String AUTHORIZE_URL = "http://www.sandbox.freelancer.com/users/api-token/auth.php?oauth_token="; + private static final String PROTECTED_RESOURCE_URL = "http://api.sandbox.freelancer.com/Job/getJobList.json"; + private static final String SCOPE = "http://api.sandbox.freelancer.com"; + + public static void main(String[] args) + { + OAuthService service = new ServiceBuilder() + .provider(FreelancerApi.Sandbox.class) + .signatureType(SignatureType.QueryString) + .apiKey("7f5a168a0bfdbd15b4a9ea2a969661c731cdea56") + .apiSecret("7bb8961b94873802f1c5344f671a518e087f5785") + .scope(SCOPE) + .build(); + Scanner in = new Scanner(System.in); + + System.out.println("=== " + NETWORK_NAME + "'s OAuth Workflow ==="); + System.out.println(); + + // Obtain the Request Token + System.out.println("Fetching the Request Token..."); + Token requestToken = service.getRequestToken(); + System.out.println("Got the Request Token!"); + System.out.println("(if your curious it looks like this: " + requestToken + " )"); + System.out.println(); + + System.out.println("Now go and authorize Scribe here:"); + System.out.println(AUTHORIZE_URL + requestToken.getToken()); + System.out.println("And paste the verifier here"); + System.out.print(">>"); + Verifier verifier = new Verifier(in.nextLine()); + System.out.println(); + + // Trade the Request Token and Verfier for the Access Token + System.out.println("Trading the Request Token for an Access Token..."); + Token accessToken = service.getAccessToken(requestToken, verifier); + System.out.println("Got the Access Token!"); + System.out.println("(if your curious it looks like this: " + accessToken + " )"); + System.out.println(); + + // Now let's go and ask for a protected resource! + System.out.println("Now we're going to access a protected resource..."); + OAuthRequest request = new OAuthRequest(Verb.GET, PROTECTED_RESOURCE_URL); + service.signRequest(accessToken, request); + request.addHeader("GData-Version", "3.0"); + Response response = request.send(); + System.out.println("Got it! Lets see what we found..."); + System.out.println(); + System.out.println(response.getCode()); + System.out.println(response.getBody()); + + System.out.println(); + System.out.println("Thats it man! Go and build something awesome with Scribe! :)"); + } +} diff --git a/src/main/resources/scribe-java-project/src/test/java/org/scribe/examples/GoogleExample.java b/src/main/resources/scribe-java-project/src/test/java/org/scribe/examples/GoogleExample.java new file mode 100644 index 0000000..fef1b43 --- /dev/null +++ b/src/main/resources/scribe-java-project/src/test/java/org/scribe/examples/GoogleExample.java @@ -0,0 +1,66 @@ +package org.scribe.examples; + +import java.util.*; + +import org.scribe.builder.*; +import org.scribe.builder.api.*; +import org.scribe.model.*; +import org.scribe.oauth.*; + +public class GoogleExample +{ + private static final String NETWORK_NAME = "Google"; + private static final String AUTHORIZE_URL = "https://www.google.com/accounts/OAuthAuthorizeToken?oauth_token="; + private static final String PROTECTED_RESOURCE_URL = "https://docs.google.com/feeds/default/private/full/"; + private static final String SCOPE = "https://docs.google.com/feeds/"; + + public static void main(String[] args) + { + OAuthService service = new ServiceBuilder() + .provider(GoogleApi.class) + .apiKey("anonymous") + .apiSecret("anonymous") + .scope(SCOPE) + .build(); + Scanner in = new Scanner(System.in); + + System.out.println("=== " + NETWORK_NAME + "'s OAuth Workflow ==="); + System.out.println(); + + // Obtain the Request Token + System.out.println("Fetching the Request Token..."); + Token requestToken = service.getRequestToken(); + System.out.println("Got the Request Token!"); + System.out.println("(if your curious it looks like this: " + requestToken + " )"); + System.out.println(); + + System.out.println("Now go and authorize Scribe here:"); + System.out.println(AUTHORIZE_URL + requestToken.getToken()); + System.out.println("And paste the verifier here"); + System.out.print(">>"); + Verifier verifier = new Verifier(in.nextLine()); + System.out.println(); + + // Trade the Request Token and Verfier for the Access Token + System.out.println("Trading the Request Token for an Access Token..."); + Token accessToken = service.getAccessToken(requestToken, verifier); + System.out.println("Got the Access Token!"); + System.out.println("(if your curious it looks like this: " + accessToken + " )"); + System.out.println(); + + // Now let's go and ask for a protected resource! + System.out.println("Now we're going to access a protected resource..."); + OAuthRequest request = new OAuthRequest(Verb.GET, PROTECTED_RESOURCE_URL); + service.signRequest(accessToken, request); + request.addHeader("GData-Version", "3.0"); + Response response = request.send(); + System.out.println("Got it! Lets see what we found..."); + System.out.println(); + System.out.println(response.getCode()); + System.out.println(response.getBody()); + + System.out.println(); + System.out.println("Thats it man! Go and build something awesome with Scribe! :)"); + + } +} \ No newline at end of file diff --git a/src/main/resources/scribe-java-project/src/test/java/org/scribe/examples/ImgUrExample.java b/src/main/resources/scribe-java-project/src/test/java/org/scribe/examples/ImgUrExample.java new file mode 100644 index 0000000..93fe91c --- /dev/null +++ b/src/main/resources/scribe-java-project/src/test/java/org/scribe/examples/ImgUrExample.java @@ -0,0 +1,58 @@ +package org.scribe.examples; + +import org.scribe.builder.*; +import org.scribe.builder.api.*; +import org.scribe.model.*; +import org.scribe.oauth.*; + +import java.util.*; + +public class ImgUrExample +{ + private static final String PROTECTED_RESOURCE_URL = "http://api.imgur.com/2/account.json"; + + public static void main(String[] args) + { + // Replace these with your own api key and secret (you'll need an read/write api key) + String apiKey = "your_app_id"; + String apiSecret = "your_api_secret"; + OAuthService service = new ServiceBuilder().provider(ImgUrApi.class).apiKey(apiKey).apiSecret(apiSecret).build(); + Scanner in = new Scanner(System.in); + + System.out.println("=== ImgUr's OAuth Workflow ==="); + System.out.println(); + + // Obtain the Request Token + System.out.println("Fetching the Request Token..."); + Token requestToken = service.getRequestToken(); + System.out.println("Got the Request Token!"); + System.out.println(); + + System.out.println("Now go and authorize Scribe here:"); + String authorizationUrl = service.getAuthorizationUrl(requestToken); + System.out.println(authorizationUrl); + System.out.println("And paste the verifier here"); + System.out.print(">>"); + Verifier verifier = new Verifier(in.nextLine()); + System.out.println(); + + // Trade the Request Token and Verfier for the Access Token + System.out.println("Trading the Request Token for an Access Token..."); + Token accessToken = service.getAccessToken(requestToken, verifier); + System.out.println("Got the Access Token!"); + System.out.println("(if your curious it looks like this: " + accessToken + " )"); + System.out.println(); + + // Now let's go and ask for a protected resource! + System.out.println("Now we're going to access a protected resource..."); + OAuthRequest request = new OAuthRequest(Verb.GET, PROTECTED_RESOURCE_URL); + service.signRequest(accessToken, request); + Response response = request.send(); + System.out.println("Got it! Lets see what we found..."); + System.out.println(); + System.out.println(response.getBody()); + + System.out.println(); + System.out.println("Thats it man! Go and build something awesome with Scribe! :)"); + } +} diff --git a/src/main/resources/scribe-java-project/src/test/java/org/scribe/examples/Kaixin20Example.java b/src/main/resources/scribe-java-project/src/test/java/org/scribe/examples/Kaixin20Example.java new file mode 100644 index 0000000..b3e9d66 --- /dev/null +++ b/src/main/resources/scribe-java-project/src/test/java/org/scribe/examples/Kaixin20Example.java @@ -0,0 +1,63 @@ +package org.scribe.examples; + +import org.scribe.builder.*; +import org.scribe.builder.api.*; +import org.scribe.model.*; +import org.scribe.oauth.*; +import java.util.*; + +public class Kaixin20Example +{ + private static final String NETWORK_NAME = "Kaixin"; + private static final String PROTECTED_RESOURCE_URL = "https://api.kaixin001.com/users/me.json"; + private static final Token EMPTY_TOKEN = null; + + public static void main(String[] args) + { + // Replace these with your own api key and secret + String apiKey = "your api key"; + String apiSecret = "your api secret"; + OAuthService service = new ServiceBuilder() + .provider(KaixinApi20.class) + .apiKey(apiKey) + .apiSecret(apiSecret) + .callback("http://your.domain.com/handle") + .build(); + Scanner in = new Scanner(System.in); + + System.out.println("=== " + NETWORK_NAME + "'s OAuth Workflow ==="); + System.out.println(); + + // Obtain the Authorization URL + System.out.println("Fetching the Authorization URL..."); + String authorizationUrl = service.getAuthorizationUrl(EMPTY_TOKEN); + System.out.println("Got the Authorization URL!"); + System.out.println("Now go and authorize Scribe here:"); + System.out.println(authorizationUrl); + System.out.println("And paste the authorization code here"); + System.out.print(">>"); + Verifier verifier = new Verifier(in.nextLine()); + System.out.println(); + + // Trade the Request Token and Verifier for the Access Token + System.out.println("Trading the Request Token for an Access Token..."); + Token accessToken = service.getAccessToken(EMPTY_TOKEN, verifier); + System.out.println("Got the Access Token!"); + System.out.println("(if your curious it looks like this: " + accessToken + " )"); + System.out.println(); + + // Now let's go and ask for a protected resource! + System.out.println("Now we're going to access a protected resource..."); + OAuthRequest request = new OAuthRequest(Verb.GET, PROTECTED_RESOURCE_URL); + service.signRequest(accessToken, request); + Response response = request.send(); + System.out.println("Got it! Lets see what we found..."); + System.out.println(); + System.out.println(response.getCode()); + System.out.println(response.getBody()); + + System.out.println(); + System.out.println("Thats it man! Go and build something awesome with Scribe! :)"); + + } +} diff --git a/src/main/resources/scribe-java-project/src/test/java/org/scribe/examples/LinkedInExample.java b/src/main/resources/scribe-java-project/src/test/java/org/scribe/examples/LinkedInExample.java new file mode 100644 index 0000000..703cc82 --- /dev/null +++ b/src/main/resources/scribe-java-project/src/test/java/org/scribe/examples/LinkedInExample.java @@ -0,0 +1,59 @@ +package org.scribe.examples; + +import java.util.Scanner; + +import org.scribe.builder.*; +import org.scribe.builder.api.*; +import org.scribe.model.*; +import org.scribe.oauth.*; + +public class LinkedInExample +{ + private static final String PROTECTED_RESOURCE_URL = "http://api.linkedin.com/v1/people/~/connections:(id,last-name)"; + + public static void main(String[] args) + { + OAuthService service = new ServiceBuilder() + .provider(LinkedInApi.class) + .apiKey("CiEgwWDkA5BFpNrc0RfGyVuSlOh4tig5kOTZ9q97qcXNrFl7zqk-Ts7DqRGaKDCV") + .apiSecret("dhho4dfoCmiQXrkw4yslork5XWLFnPSuMR-8gscPVjY4jqFFHPYWJKgpFl4uLTM6") + .build(); + Scanner in = new Scanner(System.in); + + System.out.println("=== LinkedIn's OAuth Workflow ==="); + System.out.println(); + + // Obtain the Request Token + System.out.println("Fetching the Request Token..."); + Token requestToken = service.getRequestToken(); + System.out.println("Got the Request Token!"); + System.out.println(); + + System.out.println("Now go and authorize Scribe here:"); + System.out.println(service.getAuthorizationUrl(requestToken)); + System.out.println("And paste the verifier here"); + System.out.print(">>"); + Verifier verifier = new Verifier(in.nextLine()); + System.out.println(); + + // Trade the Request Token and Verfier for the Access Token + System.out.println("Trading the Request Token for an Access Token..."); + Token accessToken = service.getAccessToken(requestToken, verifier); + System.out.println("Got the Access Token!"); + System.out.println("(if your curious it looks like this: " + accessToken + " )"); + System.out.println(); + + // Now let's go and ask for a protected resource! + System.out.println("Now we're going to access a protected resource..."); + OAuthRequest request = new OAuthRequest(Verb.GET, PROTECTED_RESOURCE_URL); + service.signRequest(accessToken, request); + Response response = request.send(); + System.out.println("Got it! Lets see what we found..."); + System.out.println(); + System.out.println(response.getBody()); + + System.out.println(); + System.out.println("Thats it man! Go and build something awesome with Scribe! :)"); + } + +} diff --git a/src/main/resources/scribe-java-project/src/test/java/org/scribe/examples/LinkedInExampleWithScopes.java b/src/main/resources/scribe-java-project/src/test/java/org/scribe/examples/LinkedInExampleWithScopes.java new file mode 100644 index 0000000..b8e8b28 --- /dev/null +++ b/src/main/resources/scribe-java-project/src/test/java/org/scribe/examples/LinkedInExampleWithScopes.java @@ -0,0 +1,59 @@ +package org.scribe.examples; + +import java.util.Scanner; + +import org.scribe.builder.*; +import org.scribe.builder.api.*; +import org.scribe.model.*; +import org.scribe.oauth.*; + +public class LinkedInExampleWithScopes +{ + private static final String PROTECTED_RESOURCE_URL = "http://api.linkedin.com/v1/people/~/connections:(id,last-name)"; + + public static void main(String[] args) + { + OAuthService service = new ServiceBuilder() + .provider(LinkedInApi.withScopes("foo", "bar", "baz")) + .apiKey("CiEgwWDkA5BFpNrc0RfGyVuSlOh4tig5kOTZ9q97qcXNrFl7zqk-Ts7DqRGaKDCV") + .apiSecret("dhho4dfoCmiQXrkw4yslork5XWLFnPSuMR-8gscPVjY4jqFFHPYWJKgpFl4uLTM6") + .build(); + Scanner in = new Scanner(System.in); + + System.out.println("=== LinkedIn's OAuth Workflow ==="); + System.out.println(); + + // Obtain the Request Token + System.out.println("Fetching the Request Token..."); + Token requestToken = service.getRequestToken(); + System.out.println("Got the Request Token!"); + System.out.println(); + + System.out.println("Now go and authorize Scribe here:"); + System.out.println(service.getAuthorizationUrl(requestToken)); + System.out.println("And paste the verifier here"); + System.out.print(">>"); + Verifier verifier = new Verifier(in.nextLine()); + System.out.println(); + + // Trade the Request Token and Verfier for the Access Token + System.out.println("Trading the Request Token for an Access Token..."); + Token accessToken = service.getAccessToken(requestToken, verifier); + System.out.println("Got the Access Token!"); + System.out.println("(if your curious it looks like this: " + accessToken + " )"); + System.out.println(); + + // Now let's go and ask for a protected resource! + System.out.println("Now we're going to access a protected resource..."); + OAuthRequest request = new OAuthRequest(Verb.GET, PROTECTED_RESOURCE_URL); + service.signRequest(accessToken, request); + Response response = request.send(); + System.out.println("Got it! Lets see what we found..."); + System.out.println(); + System.out.println(response.getBody()); + + System.out.println(); + System.out.println("Thats it man! Go and build something awesome with Scribe! :)"); + } + +} diff --git a/src/main/resources/scribe-java-project/src/test/java/org/scribe/examples/LiveExample.java b/src/main/resources/scribe-java-project/src/test/java/org/scribe/examples/LiveExample.java new file mode 100644 index 0000000..ade5a6b --- /dev/null +++ b/src/main/resources/scribe-java-project/src/test/java/org/scribe/examples/LiveExample.java @@ -0,0 +1,64 @@ +package org.scribe.examples; + +import java.util.*; + +import org.scribe.builder.*; +import org.scribe.builder.api.*; +import org.scribe.model.*; +import org.scribe.oauth.*; + +public class LiveExample +{ + private static final String PROTECTED_RESOURCE_URL = "https://api.foursquare.com/v2/users/self/friends?oauth_token="; + private static final Token EMPTY_TOKEN = null; + + public static void main(String[] args) + { + // Replace these with your own api key and secret + String apiKey = ""; + String apiSecret = ""; + OAuthService service = new ServiceBuilder() + .provider(LiveApi.class) + .apiKey(apiKey) + .apiSecret(apiSecret) + .scope("wl.basic") + .callback("http://localhost:9000/") + .build(); + Scanner in = new Scanner(System.in); + + System.out.println("=== Windows Live's OAuth Workflow ==="); + System.out.println(); + + // Obtain the Authorization URL + System.out.println("Fetching the Authorization URL..."); + String authorizationUrl = service.getAuthorizationUrl(EMPTY_TOKEN); + System.out.println("Got the Authorization URL!"); + System.out.println("Now go and authorize Scribe here:"); + System.out.println(authorizationUrl); + System.out.println("And paste the authorization code here"); + System.out.print(">>"); + Verifier verifier = new Verifier(in.nextLine()); + System.out.println(); + + // Trade the Request Token and Verfier for the Access Token + System.out.println("Trading the Request Token for an Access Token..."); + Token accessToken = service.getAccessToken(EMPTY_TOKEN, verifier); + System.out.println("Got the Access Token!"); + System.out.println("(if your curious it looks like this: " + accessToken + " )"); + System.out.println(); + + // Now let's go and ask for a protected resource! + System.out.println("Now we're going to access a protected resource..."); + OAuthRequest request = new OAuthRequest(Verb.GET, PROTECTED_RESOURCE_URL + accessToken.getToken()); + service.signRequest(accessToken, request); + Response response = request.send(); + System.out.println("Got it! Lets see what we found..."); + System.out.println(); + System.out.println(response.getCode()); + System.out.println(response.getBody()); + + System.out.println(); + System.out.println("Thats it man! Go and build something awesome with Scribe! :)"); + + } +} diff --git a/src/main/resources/scribe-java-project/src/test/java/org/scribe/examples/LoveFilmExample.java b/src/main/resources/scribe-java-project/src/test/java/org/scribe/examples/LoveFilmExample.java new file mode 100644 index 0000000..9e80016 --- /dev/null +++ b/src/main/resources/scribe-java-project/src/test/java/org/scribe/examples/LoveFilmExample.java @@ -0,0 +1,64 @@ +package org.scribe.examples; + +import java.util.*; + +import org.scribe.builder.*; +import org.scribe.builder.api.*; +import org.scribe.model.*; +import org.scribe.oauth.*; + +public class LoveFilmExample +{ + private static final String NETWORK_NAME = "LoveFilm"; + private static final String PROTECTED_RESOURCE_URL = "https://api.lovefilm.com/users"; + + public static void main(String[] args) + { + // Replace these with your own api key and secret + String apiKey = "your_key"; + String apiSecret = "your_secret"; + OAuthService service = new ServiceBuilder().provider(LoveFilmApi.class).apiKey(apiKey).apiSecret(apiSecret).build(); + Scanner in = new Scanner(System.in); + + System.out.println("=== " + NETWORK_NAME + "'s OAuth Workflow ==="); + System.out.println(); + + // Grab a request token. + System.out.println("Fetching request token."); + Token requestToken = service.getRequestToken(); + System.out.println("Got it ... "); + System.out.println(requestToken.getToken()); + + // Obtain the Authorization URL + System.out.println("Fetching the Authorization URL..."); + String authorizationUrl = service.getAuthorizationUrl(requestToken); + System.out.println("Got the Authorization URL!"); + System.out.println("Now go and authorize Scribe here:"); + System.out.println(authorizationUrl); + System.out.println("And paste the authorization code here"); + System.out.print(">>"); + Verifier verifier = new Verifier(in.nextLine()); + System.out.println(); + + // Trade the Request Token and Verfier for the Access Token + System.out.println("Trading the Request Token for an Access Token..."); + Token accessToken = service.getAccessToken(requestToken, verifier); + System.out.println("Got the Access Token!"); + System.out.println("(if your curious it looks like this: " + accessToken + " )"); + System.out.println(); + + // Now let's go and ask for a protected resource! + System.out.println("Now we're going to access a protected resource..."); + OAuthRequest request = new OAuthRequest(Verb.GET, PROTECTED_RESOURCE_URL); + service.signRequest(accessToken, request); + Response response = request.send(); + System.out.println("Got it! Lets see what we found..."); + System.out.println(); + System.out.println(response.getCode()); + System.out.println(response.getBody()); + + System.out.println(); + System.out.println("Thats it man! Go and build something awesome with Scribe! :)"); + + } +} diff --git a/src/main/resources/scribe-java-project/src/test/java/org/scribe/examples/MeetupExample.java b/src/main/resources/scribe-java-project/src/test/java/org/scribe/examples/MeetupExample.java new file mode 100644 index 0000000..2185b5c --- /dev/null +++ b/src/main/resources/scribe-java-project/src/test/java/org/scribe/examples/MeetupExample.java @@ -0,0 +1,62 @@ +package org.scribe.examples; + +import java.util.Scanner; + +import org.scribe.builder.ServiceBuilder; +import org.scribe.builder.api.MeetupApi; +import org.scribe.model.OAuthRequest; +import org.scribe.model.Response; +import org.scribe.model.Token; +import org.scribe.model.Verb; +import org.scribe.model.Verifier; +import org.scribe.oauth.OAuthService; + +public class MeetupExample +{ + private static final String PROTECTED_RESOURCE_URL = "http://api.meetup.com/2/member/self"; + + public static void main(String[] args) + { + OAuthService service = new ServiceBuilder() + .provider(MeetupApi.class) + .apiKey("j1khkp0dus323ftve0sdcv6ffe") + .apiSecret("6s6gt6q59gvfjtsvgcmht62gq4") + .build(); + Scanner in = new Scanner(System.in); + + System.out.println("=== Meetup's OAuth Workflow ==="); + System.out.println(); + + // Obtain the Request Token + System.out.println("Fetching the Request Token..."); + Token requestToken = service.getRequestToken(); + System.out.println("Got the Request Token!"); + System.out.println(); + + System.out.println("Now go and authorize Scribe here:"); + System.out.println(service.getAuthorizationUrl(requestToken)); + System.out.println("And paste the verifier here"); + System.out.print(">>"); + Verifier verifier = new Verifier(in.nextLine()); + System.out.println(); + + // Trade the Request Token and Verfier for the Access Token + System.out.println("Trading the Request Token for an Access Token..."); + Token accessToken = service.getAccessToken(requestToken, verifier); + System.out.println("Got the Access Token!"); + System.out.println("(if your curious it looks like this: " + accessToken + " )"); + System.out.println(); + + // Now let's go and ask for a protected resource! + System.out.println("Now we're going to access a protected resource..."); + OAuthRequest request = new OAuthRequest(Verb.GET, PROTECTED_RESOURCE_URL); + service.signRequest(accessToken, request); + Response response = request.send(); + System.out.println("Got it! Lets see what we found..."); + System.out.println(); + System.out.println(response.getBody()); + + System.out.println(); + System.out.println("Thats it man! Go and build something awesome with Scribe! :)"); + } +} diff --git a/src/main/resources/scribe-java-project/src/test/java/org/scribe/examples/NeteaseWeiboExample.java b/src/main/resources/scribe-java-project/src/test/java/org/scribe/examples/NeteaseWeiboExample.java new file mode 100644 index 0000000..e65335e --- /dev/null +++ b/src/main/resources/scribe-java-project/src/test/java/org/scribe/examples/NeteaseWeiboExample.java @@ -0,0 +1,68 @@ +package org.scribe.examples; + +import java.util.*; + +import org.scribe.builder.*; +import org.scribe.builder.api.*; +import org.scribe.model.*; +import org.scribe.oauth.*; + +public class NeteaseWeiboExample +{ + private static final String NETWORK_NAME = "NetEase(163.com) Weibo"; + private static final String PROTECTED_RESOURCE_URL = "http://api.t.163.com/account/verify_credentials.json"; + + public static void main(String[] args) + { + // Replace these with your own api key and secret + String apiKey = "your key"; + String apiSecret = "your secret"; + OAuthService service = new ServiceBuilder() + .provider(NeteaseWeibooApi.class) + .apiKey(apiKey) + .apiSecret(apiSecret) + .build(); + Scanner in = new Scanner(System.in); + + System.out.println("=== " + NETWORK_NAME + "'s OAuth Workflow ==="); + System.out.println(); + + // Grab a request token. + System.out.println("Fetching request token."); + Token requestToken = service.getRequestToken(); + System.out.println("Got it ... "); + System.out.println(requestToken.getToken()); + + // Obtain the Authorization URL + System.out.println("Fetching the Authorization URL..."); + String authorizationUrl = service.getAuthorizationUrl(requestToken); + System.out.println("Got the Authorization URL!"); + System.out.println("Now go and authorize Scribe here:"); + System.out.println(authorizationUrl); + System.out.println("And paste the authorization code here"); + System.out.print(">>"); + Verifier verifier = new Verifier(in.nextLine()); + System.out.println(); + + // Trade the Request Token and Verfier for the Access Token + System.out.println("Trading the Request Token for an Access Token..."); + Token accessToken = service.getAccessToken(requestToken, verifier); + System.out.println("Got the Access Token!"); + System.out.println("(if your curious it looks like this: " + + accessToken + " )"); + System.out.println(); + + // Now let's go and ask for a protected resource! + System.out.println("Now we're going to access a protected resource..."); + OAuthRequest request = new OAuthRequest(Verb.GET, PROTECTED_RESOURCE_URL); + service.signRequest(accessToken, request); + Response response = request.send(); + System.out.println("Got it! Lets see what we found..."); + System.out.println(); + System.out.println(response.getCode()); + System.out.println(response.getBody()); + + System.out.println(); + System.out.println("Thats it man! Go and build something awesome with Scribe! :)"); + } +} diff --git a/src/main/resources/scribe-java-project/src/test/java/org/scribe/examples/Px500Example.java b/src/main/resources/scribe-java-project/src/test/java/org/scribe/examples/Px500Example.java new file mode 100644 index 0000000..cdbe449 --- /dev/null +++ b/src/main/resources/scribe-java-project/src/test/java/org/scribe/examples/Px500Example.java @@ -0,0 +1,60 @@ +package org.scribe.examples; + +import java.util.Scanner; + +import org.scribe.builder.*; +import org.scribe.builder.api.*; +import org.scribe.model.*; +import org.scribe.oauth.*; + +public class Px500Example +{ + private static final String PROTECTED_RESOURCE_URL = "https://api.500px.com/v1/"; + + public static void main(String[] args) + { + OAuthService service = new ServiceBuilder() + .provider(Px500Api.class) + .apiKey("your-api-key") + .apiSecret("your-api-secret") + .build(); + Scanner in = new Scanner(System.in); + + System.out.println("=== 500Px's OAuth Workflow ==="); + System.out.println(); + + // Obtain the Request Token + System.out.println("Fetching the Request Token..."); + Token requestToken = service.getRequestToken(); + System.out.println("Got the Request Token!"); + System.out.println(); + + System.out.println("Now go and authorize Scribe here:"); + System.out.println(service.getAuthorizationUrl(requestToken)); + System.out.println("And paste the verifier here"); + System.out.print(">>"); + Verifier verifier = new Verifier(in.nextLine()); + System.out.println(); + + // Trade the Request Token and Verfier for the Access Token + System.out.println("Trading the Request Token for an Access Token..."); + Token accessToken = service.getAccessToken(requestToken, verifier); + System.out.println("Got the Access Token!"); + System.out.println("(if your curious it looks like this: " + accessToken + " )"); + System.out.println(); + + // Now let's go and ask for a protected resource! + System.out.println("Now we're going to access a protected resource..."); + OAuthRequest request = new OAuthRequest(Verb.GET, PROTECTED_RESOURCE_URL); + service.signRequest(accessToken, request); + Response response = request.send(); + System.out.println("Got it! Lets see what we found..."); + System.out.println(); + System.out.println(response.getBody()); + + System.out.println(); + System.out.println("Thats it man! Go and build something awesome with Scribe! :)"); + + } + +} \ No newline at end of file diff --git a/src/main/resources/scribe-java-project/src/test/java/org/scribe/examples/RenrenExample.java b/src/main/resources/scribe-java-project/src/test/java/org/scribe/examples/RenrenExample.java new file mode 100644 index 0000000..ae13375 --- /dev/null +++ b/src/main/resources/scribe-java-project/src/test/java/org/scribe/examples/RenrenExample.java @@ -0,0 +1,108 @@ +package org.scribe.examples; + +import org.scribe.builder.*; +import org.scribe.builder.api.*; +import org.scribe.model.*; +import org.scribe.oauth.*; +import java.nio.charset.*; +import java.security.*; +import java.util.*; + +public class RenrenExample +{ + private static final String NETWORK_NAME = "Renren"; + private static final String PROTECTED_RESOURCE_URL = "http://api.renren.com/restserver.do"; + private static final Token EMPTY_TOKEN = null; + + public static void main(String[] args) + { + // Replace these with your own api key and secret + String apiKey = "your api key"; + String apiSecret = "your api secret"; + OAuthService service = new ServiceBuilder() + .provider(RenrenApi.class) + .apiKey(apiKey) + .apiSecret(apiSecret) + .scope("status_update publish_feed") + .callback("http://your.doman.com/oauth/renren") + .build(); + Scanner in = new Scanner(System.in); + + System.out.println("=== " + NETWORK_NAME + "'s OAuth Workflow ==="); + System.out.println(); + + // Obtain the Authorization URL + System.out.println("Fetching the Authorization URL..."); + String authorizationUrl = service.getAuthorizationUrl(EMPTY_TOKEN); + System.out.println("Got the Authorization URL!"); + System.out.println("Now go and authorize Scribe here:"); + System.out.println(authorizationUrl); + System.out.println("And paste the authorization code here"); + System.out.print(">>"); + Verifier verifier = new Verifier(in.nextLine()); + System.out.println(); + + // Trade the Request Token and Verfier for the Access Token + System.out.println("Trading the Request Token for an Access Token..."); + Token accessToken = service.getAccessToken(EMPTY_TOKEN, verifier); + System.out.println("Got the Access Token!"); + System.out.println("(if your curious it looks like this: " + accessToken + " )"); + System.out.println(); + + // Now let's go and ask for a protected resource! + System.out.println("Now we're going to access a protected resource..."); + OAuthRequest request = new OAuthRequest(Verb.POST, PROTECTED_RESOURCE_URL); + Map parameters = new HashMap(); + parameters.put("method", "users.getInfo"); + parameters.put("format", "json"); + parameters.put("v", "1.0"); + + List sigString = new ArrayList(parameters.size() + 1); + for (Map.Entry entry : parameters.entrySet()) + { + request.addQuerystringParameter(entry.getKey(), entry.getValue()); + sigString.add(String.format("%s=%s", entry.getKey(), entry.getValue())); + } + sigString.add(String.format("%s=%s", OAuthConstants.ACCESS_TOKEN, accessToken.getToken())); + Collections.sort(sigString); + StringBuilder b = new StringBuilder(); + for (String param : sigString) + { + b.append(param); + } + b.append(apiSecret); + System.out.println("Sig string: " + b.toString()); + request.addQuerystringParameter("sig", md5(b.toString())); + service.signRequest(accessToken, request); + Response response = request.send(); + System.out.println("Got it! Lets see what we found..."); + System.out.println(); + System.out.println(response.getCode()); + System.out.println(response.getBody()); + + System.out.println(); + System.out.println("Thats it man! Go and build something awesome with Scribe! :)"); + + } + + public static String md5(String orgString) + { + try + { + java.security.MessageDigest md = MessageDigest.getInstance("MD5"); + byte[] array = md.digest(orgString.getBytes(Charset.forName("UTF-8"))); + StringBuffer sb = new StringBuffer(); + for (int i = 0; i < array.length; ++i) + { + sb.append(Integer.toHexString((array[i] & 0xFF) | 0x100).substring(1, 3)); + } + return sb.toString(); + } + catch (NoSuchAlgorithmException e) + { + e.printStackTrace(); + } + return null; + } + +} diff --git a/src/main/resources/scribe-java-project/src/test/java/org/scribe/examples/SinaWeibo2Example.java b/src/main/resources/scribe-java-project/src/test/java/org/scribe/examples/SinaWeibo2Example.java new file mode 100644 index 0000000..89b14e1 --- /dev/null +++ b/src/main/resources/scribe-java-project/src/test/java/org/scribe/examples/SinaWeibo2Example.java @@ -0,0 +1,63 @@ +package org.scribe.examples; + +import org.scribe.builder.*; +import org.scribe.builder.api.*; +import org.scribe.model.*; +import org.scribe.oauth.*; +import java.util.*; + +public class SinaWeibo2Example +{ + private static final String NETWORK_NAME = "SinaWeibo"; + private static final String PROTECTED_RESOURCE_URL = "https://api.weibo.com/2/account/get_uid.json"; + private static final Token EMPTY_TOKEN = null; + + public static void main(String[] args) + { + // Replace these with your own api key and secret + String apiKey = "your_api_key"; + String apiSecret = "your_api_secret"; + OAuthService service = new ServiceBuilder() + .provider(SinaWeiboApi20.class) + .apiKey(apiKey) + .apiSecret(apiSecret) + .callback("http://www.dajie.com/oauth/sina") + .build(); + Scanner in = new Scanner(System.in); + + System.out.println("=== " + NETWORK_NAME + "'s OAuth Workflow ==="); + System.out.println(); + + // Obtain the Authorization URL + System.out.println("Fetching the Authorization URL..."); + String authorizationUrl = service.getAuthorizationUrl(EMPTY_TOKEN); + System.out.println("Got the Authorization URL!"); + System.out.println("Now go and authorize Scribe here:"); + System.out.println(authorizationUrl); + System.out.println("And paste the authorization code here"); + System.out.print(">>"); + Verifier verifier = new Verifier(in.nextLine()); + System.out.println(); + + // Trade the Request Token and Verifier for the Access Token + System.out.println("Trading the Request Token for an Access Token..."); + Token accessToken = service.getAccessToken(EMPTY_TOKEN, verifier); + System.out.println("Got the Access Token!"); + System.out.println("(if your curious it looks like this: " + accessToken + " )"); + System.out.println(); + + // Now let's go and ask for a protected resource! + System.out.println("Now we're going to access a protected resource..."); + OAuthRequest request = new OAuthRequest(Verb.GET, PROTECTED_RESOURCE_URL); + service.signRequest(accessToken, request); + Response response = request.send(); + System.out.println("Got it! Lets see what we found..."); + System.out.println(); + System.out.println(response.getCode()); + System.out.println(response.getBody()); + + System.out.println(); + System.out.println("Thats it man! Go and build something awesome with Scribe! :)"); + + } +} diff --git a/src/main/resources/scribe-java-project/src/test/java/org/scribe/examples/SinaWeiboExample.java b/src/main/resources/scribe-java-project/src/test/java/org/scribe/examples/SinaWeiboExample.java new file mode 100644 index 0000000..2dc4b7c --- /dev/null +++ b/src/main/resources/scribe-java-project/src/test/java/org/scribe/examples/SinaWeiboExample.java @@ -0,0 +1,68 @@ +package org.scribe.examples; + +import java.util.*; + +import org.scribe.builder.*; +import org.scribe.builder.api.*; +import org.scribe.model.*; +import org.scribe.oauth.*; + +public class SinaWeiboExample +{ + private static final String NETWORK_NAME = "SinaWeibo"; + private static final String PROTECTED_RESOURCE_URL = "http://api.t.sina.com.cn/account/verify_credentials.json"; + + public static void main(String[] args) + { + // Replace these with your own api key and secret + String apiKey = "your key"; + String apiSecret = "your secret"; + OAuthService service = new ServiceBuilder() + .provider(SinaWeiboApi.class) + .apiKey(apiKey) + .apiSecret(apiSecret) + .build(); + Scanner in = new Scanner(System.in); + + System.out.println("=== " + NETWORK_NAME + "'s OAuth Workflow ==="); + System.out.println(); + + // Grab a request token. + System.out.println("Fetching request token."); + Token requestToken = service.getRequestToken(); + System.out.println("Got it ... "); + System.out.println(requestToken.getToken()); + + // Obtain the Authorization URL + System.out.println("Fetching the Authorization URL..."); + String authorizationUrl = service.getAuthorizationUrl(requestToken); + System.out.println("Got the Authorization URL!"); + System.out.println("Now go and authorize Scribe here:"); + System.out.println(authorizationUrl); + System.out.println("And paste the authorization code here"); + System.out.print(">>"); + Verifier verifier = new Verifier(in.nextLine()); + System.out.println(); + + // Trade the Request Token and Verfier for the Access Token + System.out.println("Trading the Request Token for an Access Token..."); + Token accessToken = service.getAccessToken(requestToken, verifier); + System.out.println("Got the Access Token!"); + System.out.println("(if your curious it looks like this: " + + accessToken + " )"); + System.out.println(); + + // Now let's go and ask for a protected resource! + System.out.println("Now we're going to access a protected resource..."); + OAuthRequest request = new OAuthRequest(Verb.GET, PROTECTED_RESOURCE_URL); + service.signRequest(accessToken, request); + Response response = request.send(); + System.out.println("Got it! Lets see what we found..."); + System.out.println(); + System.out.println(response.getCode()); + System.out.println(response.getBody()); + + System.out.println(); + System.out.println("Thats it man! Go and build something awesome with Scribe! :)"); + } +} diff --git a/src/main/resources/scribe-java-project/src/test/java/org/scribe/examples/SkyrockExample.java b/src/main/resources/scribe-java-project/src/test/java/org/scribe/examples/SkyrockExample.java new file mode 100644 index 0000000..422d067 --- /dev/null +++ b/src/main/resources/scribe-java-project/src/test/java/org/scribe/examples/SkyrockExample.java @@ -0,0 +1,61 @@ +package org.scribe.examples; + +import java.util.Scanner; + +import org.scribe.builder.*; +import org.scribe.builder.api.*; +import org.scribe.model.*; +import org.scribe.oauth.*; + +public class SkyrockExample +{ + private static final String PROTECTED_RESOURCE_URL = "https://api.skyrock.com/v2/user/get.json"; + + public static void main(String[] args) + { + OAuthService service = new ServiceBuilder() + .provider(SkyrockApi.class) + .apiKey("your-api-key") + .apiSecret("your-api-secret") + .build(); + Scanner in = new Scanner(System.in); + + System.out.println("=== Skyrock's OAuth Workflow ==="); + System.out.println(); + + // Obtain the Request Token + System.out.println("Fetching the Request Token..."); + Token requestToken = service.getRequestToken(); + System.out.println("Got the Request Token!"); + System.out.println(); + + System.out.println("Now go and authorize Scribe here:"); + System.out.println(service.getAuthorizationUrl(requestToken)); + System.out.println("And paste the verifier here"); + System.out.print(">>"); + Verifier verifier = new Verifier(in.nextLine()); + System.out.println(); + + // Trade the Request Token and Verfier for the Access Token + System.out.println("Trading the Request Token for an Access Token..."); + Token accessToken = service.getAccessToken(requestToken, verifier); + System.out.println("Got the Access Token!"); + System.out.println("(if your curious it looks like this: " + accessToken + " )"); + System.out.println(); + + // Now let's go and ask for a protected resource! + System.out.println("Now we're going to access a protected resource..."); + OAuthRequest request = new OAuthRequest(Verb.GET, PROTECTED_RESOURCE_URL); + service.signRequest(accessToken, request); + Response response = request.send(); + System.out.println("Got it! Lets see what we found..."); + System.out.println(); + System.out.println(response.getCode()); + System.out.println(response.getBody()); + + System.out.println(); + System.out.println("Thats it man! Go and build something awesome with Scribe! :)"); + + } + +} diff --git a/src/main/resources/scribe-java-project/src/test/java/org/scribe/examples/SohuWeiboExample.java b/src/main/resources/scribe-java-project/src/test/java/org/scribe/examples/SohuWeiboExample.java new file mode 100644 index 0000000..49dd9fb --- /dev/null +++ b/src/main/resources/scribe-java-project/src/test/java/org/scribe/examples/SohuWeiboExample.java @@ -0,0 +1,68 @@ +package org.scribe.examples; + +import java.util.*; + +import org.scribe.builder.*; +import org.scribe.builder.api.*; +import org.scribe.model.*; +import org.scribe.oauth.*; + +public class SohuWeiboExample +{ + private static final String NETWORK_NAME = "SohuWeibo"; + private static final String PROTECTED_RESOURCE_URL = "http://api.t.sohu.com/account/verify_credentials.json"; + + public static void main(String[] args) + { + // Replace these with your own api key and secret + String apiKey = "your_key"; + String apiSecret = "your_secret"; + OAuthService service = new ServiceBuilder() + .provider(SohuWeiboApi.class) + .apiKey(apiKey) + .apiSecret(apiSecret) + .build(); + Scanner in = new Scanner(System.in); + + System.out.println("=== " + NETWORK_NAME + "'s OAuth Workflow ==="); + System.out.println(); + + // Grab a request token. + System.out.println("Fetching request token."); + Token requestToken = service.getRequestToken(); + System.out.println("Got it ... "); + System.out.println(requestToken.getToken()); + + // Obtain the Authorization URL + System.out.println("Fetching the Authorization URL..."); + String authorizationUrl = service.getAuthorizationUrl(requestToken); + System.out.println("Got the Authorization URL!"); + System.out.println("Now go and authorize Scribe here:"); + System.out.println(authorizationUrl); + System.out.println("And paste the authorization code here"); + System.out.print(">>"); + Verifier verifier = new Verifier(in.nextLine()); + System.out.println(); + + // Trade the Request Token and Verfier for the Access Token + System.out.println("Trading the Request Token for an Access Token..."); + Token accessToken = service.getAccessToken(requestToken, verifier); + System.out.println("Got the Access Token!"); + System.out.println("(if your curious it looks like this: " + + accessToken + " )"); + System.out.println(); + + // Now let's go and ask for a protected resource! + System.out.println("Now we're going to access a protected resource..."); + OAuthRequest request = new OAuthRequest(Verb.GET, PROTECTED_RESOURCE_URL); + service.signRequest(accessToken, request); + Response response = request.send(); + System.out.println("Got it! Lets see what we found..."); + System.out.println(); + System.out.println(response.getCode()); + System.out.println(response.getBody()); + + System.out.println(); + System.out.println("Thats it man! Go and build something awesome with Scribe! :)"); + } +} diff --git a/src/main/resources/scribe-java-project/src/test/java/org/scribe/examples/TrelloExample.java b/src/main/resources/scribe-java-project/src/test/java/org/scribe/examples/TrelloExample.java new file mode 100644 index 0000000..9888f5e --- /dev/null +++ b/src/main/resources/scribe-java-project/src/test/java/org/scribe/examples/TrelloExample.java @@ -0,0 +1,60 @@ +package org.scribe.examples; + +import java.util.Scanner; + +import org.scribe.builder.*; +import org.scribe.builder.api.*; +import org.scribe.model.*; +import org.scribe.oauth.*; + +public class TrelloExample +{ + private static final String API_KEY = "your_api_key"; + private static final String API_SECRET = "your_api_secret"; + private static final String PROTECTED_RESOURCE_URL = "https://trello.com/1/members/me"; + public static void main(String[] args) + { + OAuthService service = new ServiceBuilder() + .provider(TrelloApi.class) + .apiKey(API_KEY) + .apiSecret(API_SECRET) + .build(); + Scanner in = new Scanner(System.in); + + System.out.println("=== Trello's OAuth Workflow ==="); + System.out.println(); + + // Obtain the Request Token + System.out.println("Fetching the Request Token..."); + Token requestToken = service.getRequestToken(); + System.out.println("Got the Request Token!"); + System.out.println(); + + System.out.println("Now go and authorize Scribe here:"); + System.out.println(service.getAuthorizationUrl(requestToken)); + System.out.println("And paste the verifier here"); + System.out.print(">>"); + Verifier verifier = new Verifier(in.nextLine()); + System.out.println(); + + // Trade the Request Token and Verfier for the Access Token + System.out.println("Trading the Request Token for an Access Token..."); + Token accessToken = service.getAccessToken(requestToken, verifier); + System.out.println("Got the Access Token!"); + System.out.println("(if your curious it looks like this: " + accessToken + " )"); + System.out.println(); + + // Now let's go and ask for a protected resource! + System.out.println("Now we're going to access a protected resource..."); + OAuthRequest request = new OAuthRequest(Verb.GET, PROTECTED_RESOURCE_URL); + service.signRequest(accessToken, request); + Response response = request.send(); + System.out.println("Got it! Lets see what we found..."); + System.out.println(); + System.out.println(response.getBody()); + + System.out.println(); + System.out.println("Thats it man! Go and build something awesome with Scribe! :)"); + } + +} diff --git a/src/main/resources/scribe-java-project/src/test/java/org/scribe/examples/TumblrExample.java b/src/main/resources/scribe-java-project/src/test/java/org/scribe/examples/TumblrExample.java new file mode 100644 index 0000000..d024efb --- /dev/null +++ b/src/main/resources/scribe-java-project/src/test/java/org/scribe/examples/TumblrExample.java @@ -0,0 +1,62 @@ +package org.scribe.examples; + +import java.util.Scanner; + +import org.scribe.builder.*; +import org.scribe.builder.api.*; +import org.scribe.model.*; +import org.scribe.oauth.*; + +public class TumblrExample +{ + private static final String PROTECTED_RESOURCE_URL = "http://api.tumblr.com/v2/user/info"; + + public static void main( String[] args ) + { + OAuthService service = new ServiceBuilder() + .provider( TumblrApi.class ) + .apiKey( "MY_CONSUMER_KEY" ) + .apiSecret( "MY_CONSUMER_SECRET" ) + .callback( "http://www.tumblr.com/connect/login_success.html" ) // OOB forbidden. We need an url and the better is on the tumblr website ! + .build(); + Scanner in = new Scanner( System.in ); + + System.out.println( "=== Tumblr's OAuth Workflow ===" ); + System.out.println(); + + // Obtain the Request Token + System.out.println( "Fetching the Request Token..." ); + Token requestToken = service.getRequestToken(); + System.out.println( "Got the Request Token!" ); + System.out.println(); + + System.out.println( "Now go and authorize Scribe here:" ); + System.out.println( service.getAuthorizationUrl( requestToken ) ); + System.out.println( "And paste the verifier here" ); + System.out.print( ">>" ); + Verifier verifier = new Verifier( in.nextLine() ); + System.out.println(); + + // Trade the Request Token and Verfier for the Access Token + System.out.println( "Trading the Request Token for an Access Token..." ); + Token accessToken = service.getAccessToken( requestToken , + verifier ); + System.out.println( "Got the Access Token!" ); + System.out.println( "(if your curious it looks like this: " + accessToken + " )" ); + System.out.println(); + + // Now let's go and ask for a protected resource! + System.out.println( "Now we're going to access a protected resource..." ); + OAuthRequest request = new OAuthRequest( Verb.GET , + PROTECTED_RESOURCE_URL ); + service.signRequest( accessToken , + request ); + Response response = request.send(); + System.out.println( "Got it! Lets see what we found..." ); + System.out.println(); + System.out.println( response.getBody() ); + + System.out.println(); + System.out.println( "Thats it man! Go and build something awesome with Scribe! :)" ); + } +} diff --git a/src/main/resources/scribe-java-project/src/test/java/org/scribe/examples/TwitterExample.java b/src/main/resources/scribe-java-project/src/test/java/org/scribe/examples/TwitterExample.java new file mode 100644 index 0000000..4f3435b --- /dev/null +++ b/src/main/resources/scribe-java-project/src/test/java/org/scribe/examples/TwitterExample.java @@ -0,0 +1,61 @@ +package org.scribe.examples; + +import java.util.Scanner; + +import org.scribe.builder.*; +import org.scribe.builder.api.*; +import org.scribe.model.*; +import org.scribe.oauth.*; + +public class TwitterExample +{ + private static final String PROTECTED_RESOURCE_URL = "https://api.twitter.com/1.1/account/verify_credentials.json"; + + public static void main(String[] args) + { + // If you choose to use a callback, "oauth_verifier" will be the return value by Twitter (request param) + OAuthService service = new ServiceBuilder() + .provider(TwitterApi.class) + .apiKey("6icbcAXyZx67r8uTAUM5Qw") + .apiSecret("SCCAdUUc6LXxiazxH3N0QfpNUvlUy84mZ2XZKiv39s") + .build(); + Scanner in = new Scanner(System.in); + + System.out.println("=== Twitter's OAuth Workflow ==="); + System.out.println(); + + // Obtain the Request Token + System.out.println("Fetching the Request Token..."); + Token requestToken = service.getRequestToken(); + System.out.println("Got the Request Token!"); + System.out.println(); + + System.out.println("Now go and authorize Scribe here:"); + System.out.println(service.getAuthorizationUrl(requestToken)); + System.out.println("And paste the verifier here"); + System.out.print(">>"); + Verifier verifier = new Verifier(in.nextLine()); + System.out.println(); + + // Trade the Request Token and Verfier for the Access Token + System.out.println("Trading the Request Token for an Access Token..."); + Token accessToken = service.getAccessToken(requestToken, verifier); + System.out.println("Got the Access Token!"); + System.out.println("(if your curious it looks like this: " + accessToken + " )"); + System.out.println(); + + // Now let's go and ask for a protected resource! + System.out.println("Now we're going to access a protected resource..."); + OAuthRequest request = new OAuthRequest(Verb.GET, PROTECTED_RESOURCE_URL); + request.addBodyParameter("status", "this is sparta! *"); + service.signRequest(accessToken, request); + Response response = request.send(); + System.out.println("Got it! Lets see what we found..."); + System.out.println(); + System.out.println(response.getBody()); + + System.out.println(); + System.out.println("Thats it man! Go and build something awesome with Scribe! :)"); + } + +} diff --git a/src/main/resources/scribe-java-project/src/test/java/org/scribe/examples/ViadeoExample.java b/src/main/resources/scribe-java-project/src/test/java/org/scribe/examples/ViadeoExample.java new file mode 100644 index 0000000..ebb4385 --- /dev/null +++ b/src/main/resources/scribe-java-project/src/test/java/org/scribe/examples/ViadeoExample.java @@ -0,0 +1,64 @@ +package org.scribe.examples; + +import java.util.*; + +import org.scribe.builder.*; +import org.scribe.builder.api.*; +import org.scribe.model.*; +import org.scribe.oauth.*; + +public class ViadeoExample +{ + private static final String NETWORK_NAME = "Viadeo"; + private static final String PROTECTED_RESOURCE_URL = "https://api.viadeo.com/me?user_detail=full"; + private static final Token EMPTY_TOKEN = null; + + public static void main(String[] args) + { + // Replace these with your own api key and secret + String apiKey = "your_app_id"; + String apiSecret = "your_api_secret"; + OAuthService service = new ServiceBuilder() + .provider(ViadeoApi.class) + .apiKey(apiKey) + .apiSecret(apiSecret) + .callback("http://www.example.com/oauth_callback/") + .build(); + Scanner in = new Scanner(System.in); + + System.out.println("=== " + NETWORK_NAME + "'s OAuth Workflow ==="); + System.out.println(); + + // Obtain the Authorization URL + System.out.println("Fetching the Authorization URL..."); + String authorizationUrl = service.getAuthorizationUrl(EMPTY_TOKEN); + System.out.println("Got the Authorization URL!"); + System.out.println("Now go and authorize Scribe here:"); + System.out.println(authorizationUrl); + System.out.println("And paste the authorization code here"); + System.out.print(">>"); + Verifier verifier = new Verifier(in.nextLine()); + System.out.println(); + + // Trade the Request Token and Verfier for the Access Token + System.out.println("Trading the Request Token for an Access Token..."); + Token accessToken = service.getAccessToken(EMPTY_TOKEN, verifier); + System.out.println("Got the Access Token!"); + System.out.println("(if your curious it looks like this: " + accessToken + " )"); + System.out.println(); + + // Now let's go and ask for a protected resource! + System.out.println("Now we're going to access a protected resource..."); + OAuthRequest request = new OAuthRequest(Verb.GET, PROTECTED_RESOURCE_URL); + service.signRequest(accessToken, request); + Response response = request.send(); + System.out.println("Got it! Lets see what we found..."); + System.out.println(); + System.out.println(response.getCode()); + System.out.println(response.getBody()); + + System.out.println(); + System.out.println("Thats it man! Go and build something awesome with Scribe! :)"); + + } +} diff --git a/src/main/resources/scribe-java-project/src/test/java/org/scribe/examples/VkontakteExample.java b/src/main/resources/scribe-java-project/src/test/java/org/scribe/examples/VkontakteExample.java new file mode 100644 index 0000000..f9e4134 --- /dev/null +++ b/src/main/resources/scribe-java-project/src/test/java/org/scribe/examples/VkontakteExample.java @@ -0,0 +1,68 @@ +package org.scribe.examples; + +import org.scribe.builder.*; +import org.scribe.builder.api.*; +import org.scribe.model.*; +import org.scribe.oauth.*; + +import java.util.*; + +/** + * @author Boris G. Tsirkin + * @since 20.4.2011 + */ +public class VkontakteExample +{ + private static final String NETWORK_NAME = "Vkontakte.ru"; + private static final String PROTECTED_RESOURCE_URL = "https://api.vkontakte.ru/method/friends.get"; + private static final Token EMPTY_TOKEN = null; + + public static void main(String[] args) + { + // Replace these with your own api key and secret + final String clientId = "your app id"; + final String apiSecret = "your api secret"; + OAuthService service = new ServiceBuilder() + .provider(VkontakteApi.class) + .apiKey(clientId) + .apiSecret(apiSecret) + .scope("friends,wall,offline") // replace with desired scope + .callback("http://your.site.com/callback") + .build(); + Scanner in = new Scanner(System.in); + + System.out.println("=== " + NETWORK_NAME + "'s OAuth Workflow ==="); + System.out.println(); + + // Obtain the Authorization URL + System.out.println("Fetching the Authorization URL..."); + String authorizationUrl = service.getAuthorizationUrl(EMPTY_TOKEN); + System.out.println("Got the Authorization URL!"); + System.out.println("Now go and authorize Scribe here:"); + System.out.println(authorizationUrl); + System.out.println("And paste the authorization code here"); + System.out.print(">>"); + Verifier verifier = new Verifier(in.nextLine()); + System.out.println(); + + // Trade the Request Token and Verfier for the Access Token + System.out.println("Trading the Request Token for an Access Token..."); + Token accessToken = service.getAccessToken(EMPTY_TOKEN, verifier); + System.out.println("Got the Access Token!"); + System.out.println("(if your curious it looks like this: " + accessToken + " )"); + System.out.println(); + + // Now let's go and ask for a protected resource! + System.out.println("Now we're going to access a protected resource..."); + OAuthRequest request = new OAuthRequest(Verb.GET, PROTECTED_RESOURCE_URL); + service.signRequest(accessToken, request); + Response response = request.send(); + System.out.println("Got it! Lets see what we found..."); + System.out.println(); + System.out.println(response.getCode()); + System.out.println(response.getBody()); + + System.out.println(); + System.out.println("Thats it man! Go and build something awesome with Scribe! :)"); + } +} diff --git a/src/main/resources/scribe-java-project/src/test/java/org/scribe/examples/XingExample.java b/src/main/resources/scribe-java-project/src/test/java/org/scribe/examples/XingExample.java new file mode 100755 index 0000000..93d7080 --- /dev/null +++ b/src/main/resources/scribe-java-project/src/test/java/org/scribe/examples/XingExample.java @@ -0,0 +1,59 @@ +package org.scribe.examples; + +import java.util.Scanner; + +import org.scribe.builder.*; +import org.scribe.builder.api.*; +import org.scribe.model.*; +import org.scribe.oauth.*; + +public class XingExample +{ + private static final String PROTECTED_RESOURCE_URL = "https://api.xing.com/v1/users/me"; + + public static void main(String[] args) + { + OAuthService service = new ServiceBuilder() + .provider(XingApi.class) + .apiKey("097ccfd3ef25a1cb6d75") + .apiSecret("e43364b2afd5d92f2ec28951a75bd8075f9cc221") + .build(); + Scanner in = new Scanner(System.in); + + System.out.println("=== Xing's OAuth Workflow ==="); + System.out.println(); + + // Obtain the Request Token + System.out.println("Fetching the Request Token..."); + Token requestToken = service.getRequestToken(); + System.out.println("Got the Request Token!"); + System.out.println(); + + System.out.println("Now go and authorize Scribe here:"); + System.out.println(service.getAuthorizationUrl(requestToken)); + System.out.println("And paste the verifier here"); + System.out.print(">>"); + Verifier verifier = new Verifier(in.nextLine()); + System.out.println(); + + // Trade the Request Token and Verfier for the Access Token + System.out.println("Trading the Request Token for an Access Token..."); + Token accessToken = service.getAccessToken(requestToken, verifier); + System.out.println("Got the Access Token!"); + System.out.println("(if your curious it looks like this: " + accessToken + " )"); + System.out.println(); + + // Now let's go and ask for a protected resource! + System.out.println("Now we're going to access a protected resource..."); + OAuthRequest request = new OAuthRequest(Verb.GET, PROTECTED_RESOURCE_URL); + service.signRequest(accessToken, request); + Response response = request.send(); + System.out.println("Got it! Lets see what we found..."); + System.out.println(); + System.out.println(response.getBody()); + + System.out.println(); + System.out.println("Thats it man! Go and build something awesome with Scribe! :)"); + } + +} diff --git a/src/main/resources/scribe-java-project/src/test/java/org/scribe/examples/YahooExample.java b/src/main/resources/scribe-java-project/src/test/java/org/scribe/examples/YahooExample.java new file mode 100644 index 0000000..2e3f336 --- /dev/null +++ b/src/main/resources/scribe-java-project/src/test/java/org/scribe/examples/YahooExample.java @@ -0,0 +1,60 @@ +package org.scribe.examples; + +import java.util.Scanner; + +import org.scribe.builder.*; +import org.scribe.builder.api.*; +import org.scribe.model.*; +import org.scribe.oauth.*; + +public class YahooExample +{ + private static final String PROTECTED_RESOURCE_URL = "http://social.yahooapis.com/v1/user/A6ROU63MXWDCW3Y5MGCYWVHDJI/profile/status?format=json"; + + public static void main(String[] args) + { + OAuthService service = new ServiceBuilder() + .provider(YahooApi.class) + .apiKey("dj0yJmk9TXZDWVpNVVdGaVFmJmQ9WVdrOWMweHZXbkZLTkhVbWNHbzlNVEl5TWprd05qUTJNZy0tJnM9Y29uc3VtZXJzZWNyZXQmeD0wMw--") + .apiSecret("262be559f92a2be20c4c039419018f2b48cdfce9") + .build(); + Scanner in = new Scanner(System.in); + + System.out.println("=== Yahoo's OAuth Workflow ==="); + System.out.println(); + + // Obtain the Request Token + System.out.println("Fetching the Request Token..."); + Token requestToken = service.getRequestToken(); + System.out.println("Got the Request Token!"); + System.out.println(); + + System.out.println("Now go and authorize Scribe here:"); + System.out.println(service.getAuthorizationUrl(requestToken)); + System.out.println("And paste the verifier here"); + System.out.print(">>"); + Verifier verifier = new Verifier(in.nextLine()); + System.out.println(); + + // Trade the Request Token and Verfier for the Access Token + System.out.println("Trading the Request Token for an Access Token..."); + Token accessToken = service.getAccessToken(requestToken, verifier); + System.out.println("Got the Access Token!"); + System.out.println("(if your curious it looks like this: " + accessToken + " )"); + System.out.println(); + + // Now let's go and ask for a protected resource! + System.out.println("Now we're going to access a protected resource..."); + OAuthRequest request = new OAuthRequest(Verb.GET, PROTECTED_RESOURCE_URL); + service.signRequest(accessToken, request); + Response response = request.send(); + System.out.println("Got it! Lets see what we found..."); + System.out.println(); + System.out.println(response.getCode()); + System.out.println(response.getBody()); + + System.out.println(); + System.out.println("Thats it man! Go and build something awesome with Scribe! :)"); + + } +} diff --git a/src/main/resources/scribe-java-project/src/test/java/org/scribe/extractors/BaseStringExtractorTest.java b/src/main/resources/scribe-java-project/src/test/java/org/scribe/extractors/BaseStringExtractorTest.java new file mode 100644 index 0000000..0fac082 --- /dev/null +++ b/src/main/resources/scribe-java-project/src/test/java/org/scribe/extractors/BaseStringExtractorTest.java @@ -0,0 +1,102 @@ +package org.scribe.extractors; + +import static org.junit.Assert.*; + +import org.junit.*; +import org.scribe.exceptions.*; +import org.scribe.model.*; +import org.scribe.test.helpers.*; + +public class BaseStringExtractorTest +{ + + private BaseStringExtractorImpl extractor; + private OAuthRequest request; + private OAuthRequest requestPort80; + private OAuthRequest requestPort80_2; + private OAuthRequest requestPort8080; + private OAuthRequest requestPort443; + private OAuthRequest requestPort443_2; + + @Before + public void setup() + { + request = ObjectMother.createSampleOAuthRequest(); + requestPort80 = ObjectMother.createSampleOAuthRequestPort80(); + requestPort80_2 = ObjectMother.createSampleOAuthRequestPort80_2(); + requestPort8080 = ObjectMother.createSampleOAuthRequestPort8080(); + requestPort443 = ObjectMother.createSampleOAuthRequestPort443(); + requestPort443_2 = ObjectMother.createSampleOAuthRequestPort443_2(); + extractor = new BaseStringExtractorImpl(); + } + + @Test + public void shouldExtractBaseStringFromOAuthRequest() + { + String expected = "GET&http%3A%2F%2Fexample.com&oauth_callback%3Dhttp%253A%252F%252Fexample%252Fcallback%26oauth_consumer_key%3DAS%2523%2524%255E%252A%2540%2526%26oauth_signature%3DOAuth-Signature%26oauth_timestamp%3D123456"; + String baseString = extractor.extract(request); + assertEquals(expected, baseString); + } + + @Test + public void shouldExcludePort80() + { + String expected = "GET&http%3A%2F%2Fexample.com&oauth_callback%3Dhttp%253A%252F%252Fexample%252Fcallback%26oauth_consumer_key%3DAS%2523%2524%255E%252A%2540%2526%26oauth_signature%3DOAuth-Signature%26oauth_timestamp%3D123456"; + String baseString = extractor.extract(requestPort80); + assertEquals(expected, baseString); + } + + @Test + public void shouldExcludePort80_2() + { + String expected = "GET&http%3A%2F%2Fexample.com%2Ftest&oauth_callback%3Dhttp%253A%252F%252Fexample%252Fcallback%26oauth_consumer_key%3DAS%2523%2524%255E%252A%2540%2526%26oauth_signature%3DOAuth-Signature%26oauth_timestamp%3D123456"; + String baseString = extractor.extract(requestPort80_2); + assertEquals(expected, baseString); + } + + @Test + public void shouldIncludePort8080() + { + String expected = "GET&http%3A%2F%2Fexample.com%3A8080&oauth_callback%3Dhttp%253A%252F%252Fexample%252Fcallback%26oauth_consumer_key%3DAS%2523%2524%255E%252A%2540%2526%26oauth_signature%3DOAuth-Signature%26oauth_timestamp%3D123456"; + String baseString = extractor.extract(requestPort8080); + assertEquals(expected, baseString); + } + + @Test + public void shouldExcludePort443() + { + String expected = "GET&https%3A%2F%2Fexample.com&oauth_callback%3Dhttp%253A%252F%252Fexample%252Fcallback%26oauth_consumer_key%3DAS%2523%2524%255E%252A%2540%2526%26oauth_signature%3DOAuth-Signature%26oauth_timestamp%3D123456"; + String baseString = extractor.extract(requestPort443); + assertEquals(expected, baseString); + } + + @Test + public void shouldExcludePort443_2() + { + String expected = "GET&https%3A%2F%2Fexample.com%2Ftest&oauth_callback%3Dhttp%253A%252F%252Fexample%252Fcallback%26oauth_consumer_key%3DAS%2523%2524%255E%252A%2540%2526%26oauth_signature%3DOAuth-Signature%26oauth_timestamp%3D123456"; + String baseString = extractor.extract(requestPort443_2); + assertEquals(expected, baseString); + } + + @Test(expected = IllegalArgumentException.class) + public void shouldThrowExceptionIfRquestIsNull() + { + OAuthRequest nullRequest = null; + extractor.extract(nullRequest); + } + + @Test(expected = OAuthParametersMissingException.class) + public void shouldThrowExceptionIfRquestHasNoOAuthParameters() + { + OAuthRequest request = new OAuthRequest(Verb.GET, "http://example.com"); + extractor.extract(request); + } + + @Test + public void shouldProperlyEncodeSpaces() + { + String expected = "GET&http%3A%2F%2Fexample.com&body%3Dthis%2520param%2520has%2520whitespace%26oauth_callback%3Dhttp%253A%252F%252Fexample%252Fcallback%26oauth_consumer_key%3DAS%2523%2524%255E%252A%2540%2526%26oauth_signature%3DOAuth-Signature%26oauth_timestamp%3D123456"; + request.addBodyParameter("body", "this param has whitespace"); + assertEquals(expected, extractor.extract(request)); + } +} diff --git a/src/main/resources/scribe-java-project/src/test/java/org/scribe/extractors/HeaderExtractorTest.java b/src/main/resources/scribe-java-project/src/test/java/org/scribe/extractors/HeaderExtractorTest.java new file mode 100644 index 0000000..bdc727c --- /dev/null +++ b/src/main/resources/scribe-java-project/src/test/java/org/scribe/extractors/HeaderExtractorTest.java @@ -0,0 +1,45 @@ +package org.scribe.extractors; + +import static org.junit.Assert.*; + +import org.junit.*; +import org.scribe.exceptions.*; +import org.scribe.model.*; +import org.scribe.test.helpers.*; + +public class HeaderExtractorTest +{ + + private HeaderExtractorImpl extractor; + private OAuthRequest request; + + @Before + public void setup() + { + request = ObjectMother.createSampleOAuthRequest(); + extractor = new HeaderExtractorImpl(); + } + + @Test + public void shouldExtractStandardHeader() + { + String expected = "OAuth oauth_callback=\"http%3A%2F%2Fexample%2Fcallback\", " + "oauth_signature=\"OAuth-Signature\", " + + "oauth_consumer_key=\"AS%23%24%5E%2A%40%26\", " + "oauth_timestamp=\"123456\""; + String header = extractor.extract(request); + assertEquals(expected, header); + } + + @Test(expected = IllegalArgumentException.class) + public void shouldExceptionIfRequestIsNull() + { + OAuthRequest nullRequest = null; + extractor.extract(nullRequest); + } + + @Test(expected = OAuthParametersMissingException.class) + public void shouldExceptionIfRequestHasNoOAuthParams() + { + OAuthRequest emptyRequest = new OAuthRequest(Verb.GET, "http://example.com"); + extractor.extract(emptyRequest); + } +} diff --git a/src/main/resources/scribe-java-project/src/test/java/org/scribe/extractors/JsonTokenExtractorTest.java b/src/main/resources/scribe-java-project/src/test/java/org/scribe/extractors/JsonTokenExtractorTest.java new file mode 100644 index 0000000..412e131 --- /dev/null +++ b/src/main/resources/scribe-java-project/src/test/java/org/scribe/extractors/JsonTokenExtractorTest.java @@ -0,0 +1,31 @@ +package org.scribe.extractors; + +import static org.junit.Assert.*; + +import org.junit.*; +import org.scribe.model.*; + +public class JsonTokenExtractorTest +{ + private String response = "'{ \"access_token\":\"I0122HHJKLEM21F3WLPYHDKGKZULAUO4SGMV3ABKFTDT3T3X\"}'"; + private JsonTokenExtractor extractor = new JsonTokenExtractor(); + + @Test + public void shouldParseResponse() + { + Token token = extractor.extract(response); + assertEquals(token.getToken(), "I0122HHJKLEM21F3WLPYHDKGKZULAUO4SGMV3ABKFTDT3T3X"); + } + + @Test(expected=IllegalArgumentException.class) + public void shouldThrowExceptionIfForNullParameters() + { + extractor.extract(null); + } + + @Test(expected=IllegalArgumentException.class) + public void shouldThrowExceptionIfForEmptyStrings() + { + extractor.extract(""); + } +} diff --git a/src/main/resources/scribe-java-project/src/test/java/org/scribe/extractors/TokenExtractor20Test.java b/src/main/resources/scribe-java-project/src/test/java/org/scribe/extractors/TokenExtractor20Test.java new file mode 100644 index 0000000..0fde22f --- /dev/null +++ b/src/main/resources/scribe-java-project/src/test/java/org/scribe/extractors/TokenExtractor20Test.java @@ -0,0 +1,67 @@ +package org.scribe.extractors; + +import static org.junit.Assert.*; + +import org.junit.*; +import org.scribe.exceptions.*; +import org.scribe.model.*; + +public class TokenExtractor20Test +{ + + private TokenExtractor20Impl extractor; + + @Before + public void setup() + { + extractor = new TokenExtractor20Impl(); + } + + @Test + public void shouldExtractTokenFromOAuthStandardResponse() + { + String response = "access_token=166942940015970|2.2ltzWXYNDjCtg5ZDVVJJeg__.3600.1295816400-548517159|RsXNdKrpxg8L6QNLWcs2TVTmcaE"; + Token extracted = extractor.extract(response); + assertEquals("166942940015970|2.2ltzWXYNDjCtg5ZDVVJJeg__.3600.1295816400-548517159|RsXNdKrpxg8L6QNLWcs2TVTmcaE", extracted.getToken()); + assertEquals("", extracted.getSecret()); + } + + @Test + public void shouldExtractTokenFromResponseWithExpiresParam() + { + String response = "access_token=166942940015970|2.2ltzWXYNDjCtg5ZDVVJJeg__.3600.1295816400-548517159|RsXNdKrpxg8L6QNLWcs2TVTmcaE&expires=5108"; + Token extracted = extractor.extract(response); + assertEquals("166942940015970|2.2ltzWXYNDjCtg5ZDVVJJeg__.3600.1295816400-548517159|RsXNdKrpxg8L6QNLWcs2TVTmcaE", extracted.getToken()); + assertEquals("", extracted.getSecret()); + } + + @Test + public void shouldExtractTokenFromResponseWithManyParameters() + { + String response = "access_token=foo1234&other_stuff=yeah_we_have_this_too&number=42"; + Token extracted = extractor.extract(response); + assertEquals("foo1234", extracted.getToken()); + assertEquals("", extracted.getSecret()); + } + + @Test(expected = OAuthException.class) + public void shouldThrowExceptionIfTokenIsAbsent() + { + String response = "&expires=5108"; + extractor.extract(response); + } + + @Test(expected = IllegalArgumentException.class) + public void shouldThrowExceptionIfResponseIsNull() + { + String response = null; + extractor.extract(response); + } + + @Test(expected = IllegalArgumentException.class) + public void shouldThrowExceptionIfResponseIsEmptyString() + { + String response = ""; + extractor.extract(response); + } +} diff --git a/src/main/resources/scribe-java-project/src/test/java/org/scribe/extractors/TokenExtractorTest.java b/src/main/resources/scribe-java-project/src/test/java/org/scribe/extractors/TokenExtractorTest.java new file mode 100644 index 0000000..aca5ad1 --- /dev/null +++ b/src/main/resources/scribe-java-project/src/test/java/org/scribe/extractors/TokenExtractorTest.java @@ -0,0 +1,83 @@ +package org.scribe.extractors; + +import static org.junit.Assert.*; + +import org.junit.*; +import org.scribe.exceptions.*; +import org.scribe.model.*; + +public class TokenExtractorTest +{ + + private TokenExtractorImpl extractor; + + @Before + public void setup() + { + extractor = new TokenExtractorImpl(); + } + + @Test + public void shouldExtractTokenFromOAuthStandardResponse() + { + String response = "oauth_token=hh5s93j4hdidpola&oauth_token_secret=hdhd0244k9j7ao03"; + Token extracted = extractor.extract(response); + assertEquals("hh5s93j4hdidpola", extracted.getToken()); + assertEquals("hdhd0244k9j7ao03", extracted.getSecret()); + } + + @Test + public void shouldExtractTokenFromInvertedOAuthStandardResponse() + { + String response = "oauth_token_secret=hh5s93j4hdidpola&oauth_token=hdhd0244k9j7ao03"; + Token extracted = extractor.extract(response); + assertEquals("hh5s93j4hdidpola", extracted.getSecret()); + assertEquals("hdhd0244k9j7ao03", extracted.getToken()); + } + + @Test + public void shouldExtractTokenFromResponseWithCallbackConfirmed() + { + String response = "oauth_token=hh5s93j4hdidpola&oauth_token_secret=hdhd0244k9j7ao03&callback_confirmed=true"; + Token extracted = extractor.extract(response); + assertEquals("hh5s93j4hdidpola", extracted.getToken()); + assertEquals("hdhd0244k9j7ao03", extracted.getSecret()); + } + + @Test + public void shouldExtractTokenWithEmptySecret() + { + String response = "oauth_token=hh5s93j4hdidpola&oauth_token_secret="; + Token extracted = extractor.extract(response); + assertEquals("hh5s93j4hdidpola", extracted.getToken()); + assertEquals("", extracted.getSecret()); + } + + @Test(expected = OAuthException.class) + public void shouldThrowExceptionIfTokenIsAbsent() + { + String response = "oauth_secret=hh5s93j4hdidpola&callback_confirmed=true"; + extractor.extract(response); + } + + @Test(expected = OAuthException.class) + public void shouldThrowExceptionIfSecretIsAbsent() + { + String response = "oauth_token=hh5s93j4hdidpola&callback_confirmed=true"; + extractor.extract(response); + } + + @Test(expected = IllegalArgumentException.class) + public void shouldThrowExceptionIfResponseIsNull() + { + String response = null; + extractor.extract(response); + } + + @Test(expected = IllegalArgumentException.class) + public void shouldThrowExceptionIfResponseIsEmptyString() + { + String response = ""; + extractor.extract(response); + } +} diff --git a/src/main/resources/scribe-java-project/src/test/java/org/scribe/model/ConnectionStub.java b/src/main/resources/scribe-java-project/src/test/java/org/scribe/model/ConnectionStub.java new file mode 100644 index 0000000..7e93313 --- /dev/null +++ b/src/main/resources/scribe-java-project/src/test/java/org/scribe/model/ConnectionStub.java @@ -0,0 +1,86 @@ +package org.scribe.model; + +import java.io.*; +import java.net.*; +import java.util.*; + +public class ConnectionStub extends HttpURLConnection +{ + + private Map headers = new HashMap(); + private Map> responseHeaders = new HashMap>(); + private int inputStreamCalled = 0; + + public ConnectionStub() throws Exception + { + super(new URL("http://example.com")); + } + + @Override + public void setRequestProperty(String key, String value) + { + headers.put(key, value); + } + + @Override + public String getRequestProperty(String s) + { + return headers.get(s); + } + + public Map getHeaders() + { + return headers; + } + + @Override + public int getResponseCode() throws IOException + { + return 200; + } + + @Override + public InputStream getInputStream() throws IOException + { + inputStreamCalled++; + return new ByteArrayInputStream("contents".getBytes()); + } + + public int getTimesCalledInpuStream() + { + return inputStreamCalled; + } + + @Override + public OutputStream getOutputStream() throws IOException + { + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + baos.write("contents".getBytes()); + return baos; + } + + @Override + public Map> getHeaderFields() + { + return responseHeaders; + } + + public void addResponseHeader(String key, String value) + { + responseHeaders.put(key, Arrays.asList(value)); + } + + public void connect() throws IOException + { + } + + public void disconnect() + { + } + + public boolean usingProxy() + { + return false; + } + +} diff --git a/src/main/resources/scribe-java-project/src/test/java/org/scribe/model/OAuthRequestTest.java b/src/main/resources/scribe-java-project/src/test/java/org/scribe/model/OAuthRequestTest.java new file mode 100644 index 0000000..1ea2f2f --- /dev/null +++ b/src/main/resources/scribe-java-project/src/test/java/org/scribe/model/OAuthRequestTest.java @@ -0,0 +1,34 @@ +package org.scribe.model; + +import static org.junit.Assert.*; + +import org.junit.*; + +public class OAuthRequestTest +{ + + private OAuthRequest request; + + @Before + public void setup() + { + request = new OAuthRequest(Verb.GET, "http://example.com"); + } + + @Test + public void shouldAddOAuthParamters() + { + request.addOAuthParameter(OAuthConstants.TOKEN, "token"); + request.addOAuthParameter(OAuthConstants.NONCE, "nonce"); + request.addOAuthParameter(OAuthConstants.TIMESTAMP, "ts"); + request.addOAuthParameter(OAuthConstants.SCOPE, "feeds"); + + assertEquals(4, request.getOauthParameters().size()); + } + + @Test(expected = IllegalArgumentException.class) + public void shouldThrowExceptionIfParameterIsNotOAuth() + { + request.addOAuthParameter("otherParam", "value"); + } +} diff --git a/src/main/resources/scribe-java-project/src/test/java/org/scribe/model/ParameterListTest.java b/src/main/resources/scribe-java-project/src/test/java/org/scribe/model/ParameterListTest.java new file mode 100644 index 0000000..657e8e2 --- /dev/null +++ b/src/main/resources/scribe-java-project/src/test/java/org/scribe/model/ParameterListTest.java @@ -0,0 +1,91 @@ +package org.scribe.model; + +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotSame; + +/** + * @author: Pablo Fernandez + */ +public class ParameterListTest +{ + private ParameterList params; + + @Before + public void setup() + { + this.params = new ParameterList(); + } + + @Test(expected = IllegalArgumentException.class) + public void shouldThrowExceptionWhenAppendingNullMapToQuerystring() + { + String url = null; + params.appendTo(url); + } + + @Test + public void shouldAppendNothingToQuerystringIfGivenEmptyMap() + { + String url = "http://www.example.com"; + Assert.assertEquals(url, params.appendTo(url)); + } + + @Test + public void shouldAppendParametersToSimpleUrl() + { + String url = "http://www.example.com"; + String expectedUrl = "http://www.example.com?param1=value1¶m2=value%20with%20spaces"; + + params.add("param1", "value1"); + params.add("param2", "value with spaces"); + + url = params.appendTo(url); + Assert.assertEquals(url, expectedUrl); + } + + @Test + public void shouldAppendParametersToUrlWithQuerystring() + { + String url = "http://www.example.com?already=present"; + String expectedUrl = "http://www.example.com?already=present¶m1=value1¶m2=value%20with%20spaces"; + + params.add("param1", "value1"); + params.add("param2", "value with spaces"); + + url = params.appendTo(url); + Assert.assertEquals(url, expectedUrl); + } + + @Test + public void shouldProperlySortParameters() + { + params.add("param1", "v1"); + params.add("param6", "v2"); + params.add("a_param", "v3"); + params.add("param2", "v4"); + Assert.assertEquals("a_param=v3¶m1=v1¶m2=v4¶m6=v2", params.sort().asFormUrlEncodedString()); + } + + @Test + public void shouldProperlySortParametersWithTheSameName() + { + params.add("param1", "v1"); + params.add("param6", "v2"); + params.add("a_param", "v3"); + params.add("param1", "v4"); + Assert.assertEquals("a_param=v3¶m1=v1¶m1=v4¶m6=v2", params.sort().asFormUrlEncodedString()); + } + + @Test + public void shouldNotModifyTheOriginalParameterList() + { + params.add("param1", "v1"); + params.add("param6", "v2"); + + assertNotSame(params, params.sort()); + } +} diff --git a/src/main/resources/scribe-java-project/src/test/java/org/scribe/model/RequestTest.java b/src/main/resources/scribe-java-project/src/test/java/org/scribe/model/RequestTest.java new file mode 100644 index 0000000..c473e77 --- /dev/null +++ b/src/main/resources/scribe-java-project/src/test/java/org/scribe/model/RequestTest.java @@ -0,0 +1,128 @@ +package org.scribe.model; + +import static org.junit.Assert.*; + +import org.junit.*; + +public class RequestTest +{ + private Request getRequest; + private Request postRequest; + private ConnectionStub connection; + + @Before + public void setup() throws Exception + { + connection = new ConnectionStub(); + postRequest = new Request(Verb.POST, "http://example.com"); + postRequest.addBodyParameter("param", "value"); + postRequest.addBodyParameter("param with spaces", "value with spaces"); + postRequest.setConnection(connection); + getRequest = new Request(Verb.GET, "http://example.com?qsparam=value&other+param=value+with+spaces"); + getRequest.setConnection(connection); + } + + @Test + public void shouldSetRequestVerb() + { + getRequest.send(); + assertEquals("GET", connection.getRequestMethod()); + } + + @Test + public void shouldGetQueryStringParameters() + { + assertEquals(2, getRequest.getQueryStringParams().size()); + assertEquals(0, postRequest.getQueryStringParams().size()); + assertTrue(getRequest.getQueryStringParams().contains(new Parameter("qsparam", "value"))); + } + + @Test + public void shouldAddRequestHeaders() + { + getRequest.addHeader("Header", "1"); + getRequest.addHeader("Header2", "2"); + getRequest.send(); + assertEquals(2, getRequest.getHeaders().size()); + assertEquals(2, connection.getHeaders().size()); + } + + @Test + public void shouldSetBodyParamsAndAddContentLength() + { + assertEquals("param=value¶m%20with%20spaces=value%20with%20spaces", postRequest.getBodyContents()); + postRequest.send(); + assertTrue(connection.getHeaders().containsKey("Content-Length")); + } + + @Test + public void shouldSetPayloadAndHeaders() + { + postRequest.addPayload("PAYLOAD"); + postRequest.send(); + assertEquals("PAYLOAD", postRequest.getBodyContents()); + assertTrue(connection.getHeaders().containsKey("Content-Length")); + } + + @Test + public void shouldAllowAddingQuerystringParametersAfterCreation() + { + Request request = new Request(Verb.GET, "http://example.com?one=val"); + request.addQuerystringParameter("two", "other val"); + request.addQuerystringParameter("more", "params"); + assertEquals(3, request.getQueryStringParams().size()); + } + + @Test + public void shouldReturnTheCompleteUrl() + { + Request request = new Request(Verb.GET, "http://example.com?one=val"); + request.addQuerystringParameter("two", "other val"); + request.addQuerystringParameter("more", "params"); + assertEquals("http://example.com?one=val&two=other%20val&more=params", request.getCompleteUrl()); + } + + @Test + public void shouldHandleQueryStringSpaceEncodingProperly() + { + assertTrue(getRequest.getQueryStringParams().contains(new Parameter("other param","value with spaces"))); + } + + @Test + public void shouldAutomaticallyAddContentTypeForPostRequestsWithBytePayload() + { + postRequest.addPayload("PAYLOAD".getBytes()); + postRequest.send(); + assertEquals(Request.DEFAULT_CONTENT_TYPE, connection.getHeaders().get("Content-Type")); + } + + @Test + public void shouldAutomaticallyAddContentTypeForPostRequestsWithStringPayload() + { + postRequest.addPayload("PAYLOAD"); + postRequest.send(); + assertEquals(Request.DEFAULT_CONTENT_TYPE, connection.getHeaders().get("Content-Type")); + } + + @Test + public void shouldAutomaticallyAddContentTypeForPostRequestsWithBodyParameters() + { + postRequest.send(); + assertEquals(Request.DEFAULT_CONTENT_TYPE, connection.getHeaders().get("Content-Type")); + } + + @Test + public void shouldBeAbleToOverrideItsContentType() + { + postRequest.addHeader("Content-Type", "my-content-type"); + postRequest.send(); + assertEquals("my-content-type", connection.getHeaders().get("Content-Type")); + } + + @Test + public void shouldNotAddContentTypeForGetRequests() + { + getRequest.send(); + assertFalse(connection.getHeaders().containsKey("Content-Type")); + } +} \ No newline at end of file diff --git a/src/main/resources/scribe-java-project/src/test/java/org/scribe/model/ResponseTest.java b/src/main/resources/scribe-java-project/src/test/java/org/scribe/model/ResponseTest.java new file mode 100644 index 0000000..a58fc03 --- /dev/null +++ b/src/main/resources/scribe-java-project/src/test/java/org/scribe/model/ResponseTest.java @@ -0,0 +1,75 @@ +package org.scribe.model; + +import static org.junit.Assert.*; + +import java.io.*; + +import org.junit.*; + +public class ResponseTest +{ + + private Response response; + private ConnectionStub connection; + + @Before + public void setup() throws Exception + { + connection = new ConnectionStub(); + connection.addResponseHeader("one", "one"); + connection.addResponseHeader("two", "two"); + response = new Response(connection); + } + + @Test + public void shouldPopulateResponseHeaders() + { + assertEquals(2, response.getHeaders().size()); + assertEquals("one", response.getHeader("one")); + } + + @Test + public void shouldParseBodyContents() + { + assertEquals("contents", response.getBody()); + assertEquals(1, connection.getTimesCalledInpuStream()); + } + + @Test + public void shouldParseBodyContentsOnlyOnce() + { + assertEquals("contents", response.getBody()); + assertEquals("contents", response.getBody()); + assertEquals("contents", response.getBody()); + assertEquals(1, connection.getTimesCalledInpuStream()); + } + + @Test + public void shouldHandleAConnectionWithErrors() throws Exception + { + Response errResponse = new Response(new FaultyConnection()); + assertEquals(400, errResponse.getCode()); + assertEquals("errors", errResponse.getBody()); + } + + private static class FaultyConnection extends ConnectionStub + { + + public FaultyConnection() throws Exception + { + super(); + } + + @Override + public InputStream getErrorStream() + { + return new ByteArrayInputStream("errors".getBytes()); + } + + @Override + public int getResponseCode() throws IOException + { + return 400; + } + } +} diff --git a/src/main/resources/scribe-java-project/src/test/java/org/scribe/model/TokenTest.java b/src/main/resources/scribe-java-project/src/test/java/org/scribe/model/TokenTest.java new file mode 100644 index 0000000..dff59cc --- /dev/null +++ b/src/main/resources/scribe-java-project/src/test/java/org/scribe/model/TokenTest.java @@ -0,0 +1,44 @@ +package org.scribe.model; + +import static junit.framework.Assert.*; +import org.junit.*; + +public class TokenTest +{ + @Test + public void shouldTestEqualityBasedOnTokenAndSecret() throws Exception + { + Token expected = new Token("access","secret"); + Token actual = new Token("access","secret"); + + assertEquals(expected, actual); + assertEquals(actual, actual); + } + + @Test + public void shouldNotDependOnRawString() throws Exception + { + Token expected = new Token("access","secret", "raw_string"); + Token actual = new Token("access","secret", "different_raw_string"); + + assertEquals(expected, actual); + } + + @Test + public void shouldReturnSameHashCodeForEqualObjects() throws Exception + { + Token expected = new Token("access","secret"); + Token actual = new Token("access","secret"); + + assertEquals(expected.hashCode(), actual.hashCode()); + } + + @Test + public void shouldNotBeEqualToNullOrOtherObjects() throws Exception + { + Token expected = new Token("access","secret","response"); + + assertNotSame(expected, null); + assertNotSame(expected, new Object()); + } +} diff --git a/src/main/resources/scribe-java-project/src/test/java/org/scribe/services/HMACSha1SignatureServiceTest.java b/src/main/resources/scribe-java-project/src/test/java/org/scribe/services/HMACSha1SignatureServiceTest.java new file mode 100644 index 0000000..ec058a7 --- /dev/null +++ b/src/main/resources/scribe-java-project/src/test/java/org/scribe/services/HMACSha1SignatureServiceTest.java @@ -0,0 +1,59 @@ +package org.scribe.services; + +import static org.junit.Assert.*; + +import org.junit.*; +import org.scribe.exceptions.*; + +public class HMACSha1SignatureServiceTest +{ + + private HMACSha1SignatureService service; + + @Before + public void setup() + { + service = new HMACSha1SignatureService(); + } + + @Test + public void shouldReturnSignatureMethodString() + { + String expected = "HMAC-SHA1"; + assertEquals(expected, service.getSignatureMethod()); + } + + @Test + public void shouldReturnSignature() + { + String apiSecret = "api secret"; + String tokenSecret = "token secret"; + String baseString = "base string"; + String signature = "uGymw2KHOTWI699YEaoi5xyLT50="; + assertEquals(signature, service.getSignature(baseString, apiSecret, tokenSecret)); + } + + @Test(expected = OAuthException.class) + public void shouldThrowExceptionIfBaseStringIsNull() + { + service.getSignature(null, "apiSecret", "tokenSecret"); + } + + @Test(expected = OAuthException.class) + public void shouldThrowExceptionIfBaseStringIsEmpty() + { + service.getSignature(" ", "apiSecret", "tokenSecret"); + } + + @Test(expected = OAuthException.class) + public void shouldThrowExceptionIfApiSecretIsNull() + { + service.getSignature("base string", null, "tokenSecret"); + } + + @Test(expected = OAuthException.class) + public void shouldThrowExceptionIfApiSecretIsEmpty() + { + service.getSignature("base string", " ", "tokenSecret"); + } +} diff --git a/src/main/resources/scribe-java-project/src/test/java/org/scribe/services/RSASha1SignatureServiceTest.java b/src/main/resources/scribe-java-project/src/test/java/org/scribe/services/RSASha1SignatureServiceTest.java new file mode 100644 index 0000000..2e78e84 --- /dev/null +++ b/src/main/resources/scribe-java-project/src/test/java/org/scribe/services/RSASha1SignatureServiceTest.java @@ -0,0 +1,67 @@ +package org.scribe.services; + +import static org.junit.Assert.*; + +import org.junit.*; + +import javax.xml.bind.DatatypeConverter; +import java.security.*; +import java.security.spec.*; + +public class RSASha1SignatureServiceTest +{ + + RSASha1SignatureService service = new RSASha1SignatureService(getPrivateKey()); + + @Test + public void shouldReturnSignatureMethodString() + { + String expected = "RSA-SHA1"; + assertEquals(expected, service.getSignatureMethod()); + } + + @Test + public void shouldReturnSignature() + { + String apiSecret = "api secret"; + String tokenSecret = "token secret"; + String baseString = "base string"; + String signature = "LUNRzQAlpdNyM9mLXm96Va6g/qVNnEAb7p7K1KM0g8IopOFQJPoOO7cvppgt7w3QyhijWJnCmvqXaaIAGrqvdyr3fIzBULh8D/iZQUNLMi08GCOA34P81XBvsc7A5uJjPDsGhJg2MzoVJ8nWJhU/lMMk4c92S1WGskeoDofRwpo="; + assertEquals(signature, service.getSignature(baseString, apiSecret, tokenSecret)); + } + + /** + *Created primary key using openssl. + * + * openssl req -x509 -nodes -days 365 -newkey rsa:1024 -sha1 -subj '/C=GB/ST=/L=Manchester/CN=www.example.com' -keyout myrsakey.pem -out /tmp/myrsacert.pem + * openssl pkcs8 -in myrsakey.pem -topk8 -nocrypt -out myrsakey.pk8 + */ + private static PrivateKey getPrivateKey() + { + String str = "MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBAMPQ5BCMxlUq2TYy\n"+ + "iRIoEUsz6HGTJhHuasS2nx1Se4Co3lxwxyubVdFj8AuhHNJSmJvjlpbTsGOjLZpr\n"+ + "HyDEDdJmf1Fensh1MhUnBZ4a7uLrZrKzFHHJdamX9pxapB89vLeHlCot9hVXdrZH\n"+ + "nNtg6FdmRKH/8gbs8iDyIayFvzYDAgMBAAECgYA+c9MpTBy9cQsR9BAvkEPjvkx2\n"+ + "XL4ZnfbDgpNA4Nuu7yzsQrPjPomiXMNkkiAFHH67yVxwAlgRjyuuQlgNNTpKvyQt\n"+ + "XcHxffnU0820VmE23M+L7jg2TlB3+rUnEDmDvCoyjlwGDR6lNb7t7Fgg2iR+iaov\n"+ + "0iVzz+l9w0slRlyGsQJBAPWXW2m3NmFgqfDxtw8fsKC2y8o17/cnPjozRGtWb8LQ\n"+ + "g3VCb8kbOFHOYNGazq3M7+wD1qILF2h/HecgK9eQrZ0CQQDMHXoJMfKKbrFrTKgE\n"+ + "zyggO1gtuT5OXYeFewMEb5AbDI2FfSc2YP7SHij8iQ2HdukBrbTmi6qxh3HmIR58\n"+ + "I/AfAkEA0Y9vr0tombsUB8cZv0v5OYoBZvCTbMANtzfb4AOHpiKqqbohDOevLQ7/\n"+ + "SpvgVCmVaDz2PptcRAyEBZ5MCssneQJAB2pmvaDH7Ambfod5bztLfOhLCtY5EkXJ\n"+ + "n6rZcDbRaHorRhdG7m3VtDKOUKZ2DF7glkQGV33phKukErVPUzlHBwJAScD9TqaG\n"+ + "wJ3juUsVtujV23SnH43iMggXT7m82STpPGam1hPfmqu2Z0niePFo927ogQ7H1EMJ\n"+ + "UHgqXmuvk2X/Ww=="; + + try + { + KeyFactory fac = KeyFactory.getInstance("RSA"); + PKCS8EncodedKeySpec privKeySpec = new PKCS8EncodedKeySpec(DatatypeConverter.parseBase64Binary(str)); + return fac.generatePrivate(privKeySpec); + } + catch (Exception e) + { + throw new RuntimeException(e); + } + } +} diff --git a/src/main/resources/scribe-java-project/src/test/java/org/scribe/services/TimestampServiceTest.java b/src/main/resources/scribe-java-project/src/test/java/org/scribe/services/TimestampServiceTest.java new file mode 100644 index 0000000..352b962 --- /dev/null +++ b/src/main/resources/scribe-java-project/src/test/java/org/scribe/services/TimestampServiceTest.java @@ -0,0 +1,50 @@ +package org.scribe.services; + +import static org.junit.Assert.*; + +import org.junit.*; + +public class TimestampServiceTest +{ + + private TimestampServiceImpl service; + private TimestampServiceImpl.Timer timerStub; + + @Before + public void setup() + { + service = new TimestampServiceImpl(); + timerStub = new TimerStub(); + service.setTimer(timerStub); + } + + @Test + public void shouldReturnTimestampInSeconds() + { + String expected = "1000"; + assertEquals(expected, service.getTimestampInSeconds()); + } + + @Test + public void shouldReturnNonce() + { + String expected = "1042"; + assertEquals(expected, service.getNonce()); + } + + private static class TimerStub extends TimestampServiceImpl.Timer + { + + @Override + public Long getMilis() + { + return 1000000L; + } + + @Override + public Integer getRandomInteger() + { + return 42; + } + } +} diff --git a/src/main/resources/scribe-java-project/src/test/java/org/scribe/test/helpers/ObjectMother.java b/src/main/resources/scribe-java-project/src/test/java/org/scribe/test/helpers/ObjectMother.java new file mode 100644 index 0000000..abd75cc --- /dev/null +++ b/src/main/resources/scribe-java-project/src/test/java/org/scribe/test/helpers/ObjectMother.java @@ -0,0 +1,67 @@ +package org.scribe.test.helpers; + +import org.scribe.model.*; + +public class ObjectMother +{ + + public static OAuthRequest createSampleOAuthRequest() + { + OAuthRequest request = new OAuthRequest(Verb.GET, "http://example.com"); + request.addOAuthParameter(OAuthConstants.TIMESTAMP, "123456"); + request.addOAuthParameter(OAuthConstants.CONSUMER_KEY, "AS#$^*@&"); + request.addOAuthParameter(OAuthConstants.CALLBACK, "http://example/callback"); + request.addOAuthParameter(OAuthConstants.SIGNATURE, "OAuth-Signature"); + return request; + } + + public static OAuthRequest createSampleOAuthRequestPort80() + { + OAuthRequest request = new OAuthRequest(Verb.GET, "http://example.com:80"); + request.addOAuthParameter(OAuthConstants.TIMESTAMP, "123456"); + request.addOAuthParameter(OAuthConstants.CONSUMER_KEY, "AS#$^*@&"); + request.addOAuthParameter(OAuthConstants.CALLBACK, "http://example/callback"); + request.addOAuthParameter(OAuthConstants.SIGNATURE, "OAuth-Signature"); + return request; + } + + public static OAuthRequest createSampleOAuthRequestPort80_2() + { + OAuthRequest request = new OAuthRequest(Verb.GET, "http://example.com:80/test"); + request.addOAuthParameter(OAuthConstants.TIMESTAMP, "123456"); + request.addOAuthParameter(OAuthConstants.CONSUMER_KEY, "AS#$^*@&"); + request.addOAuthParameter(OAuthConstants.CALLBACK, "http://example/callback"); + request.addOAuthParameter(OAuthConstants.SIGNATURE, "OAuth-Signature"); + return request; + } + + public static OAuthRequest createSampleOAuthRequestPort8080() + { + OAuthRequest request = new OAuthRequest(Verb.GET, "http://example.com:8080"); + request.addOAuthParameter(OAuthConstants.TIMESTAMP, "123456"); + request.addOAuthParameter(OAuthConstants.CONSUMER_KEY, "AS#$^*@&"); + request.addOAuthParameter(OAuthConstants.CALLBACK, "http://example/callback"); + request.addOAuthParameter(OAuthConstants.SIGNATURE, "OAuth-Signature"); + return request; + } + + public static OAuthRequest createSampleOAuthRequestPort443() + { + OAuthRequest request = new OAuthRequest(Verb.GET, "https://example.com:443"); + request.addOAuthParameter(OAuthConstants.TIMESTAMP, "123456"); + request.addOAuthParameter(OAuthConstants.CONSUMER_KEY, "AS#$^*@&"); + request.addOAuthParameter(OAuthConstants.CALLBACK, "http://example/callback"); + request.addOAuthParameter(OAuthConstants.SIGNATURE, "OAuth-Signature"); + return request; + } + + public static OAuthRequest createSampleOAuthRequestPort443_2() + { + OAuthRequest request = new OAuthRequest(Verb.GET, "https://example.com:443/test"); + request.addOAuthParameter(OAuthConstants.TIMESTAMP, "123456"); + request.addOAuthParameter(OAuthConstants.CONSUMER_KEY, "AS#$^*@&"); + request.addOAuthParameter(OAuthConstants.CALLBACK, "http://example/callback"); + request.addOAuthParameter(OAuthConstants.SIGNATURE, "OAuth-Signature"); + return request; + } +} diff --git a/src/main/resources/scribe-java-project/src/test/java/org/scribe/utils/MapUtilsTest.java b/src/main/resources/scribe-java-project/src/test/java/org/scribe/utils/MapUtilsTest.java new file mode 100644 index 0000000..f44a0f5 --- /dev/null +++ b/src/main/resources/scribe-java-project/src/test/java/org/scribe/utils/MapUtilsTest.java @@ -0,0 +1,35 @@ +package org.scribe.utils; + +import java.util.*; +import org.junit.*; + +/** + * @author: Pablo Fernandez + */ +public class MapUtilsTest +{ + + @Test + public void shouldPrettyPrintMap() + { + Map map = new HashMap(); + map.put(1, "one"); + map.put(2, "two"); + map.put(3, "three"); + map.put(4, "four"); + Assert.assertEquals("{ 1 -> one , 2 -> two , 3 -> three , 4 -> four }", MapUtils.toString(map)); + } + + @Test + public void shouldHandleEmptyMap() + { + Map map = new HashMap(); + Assert.assertEquals("{}", MapUtils.toString(map)); + } + + @Test + public void shouldHandleNullInputs() + { + Assert.assertEquals("", MapUtils.toString(null)); + } +} diff --git a/src/main/resources/scribe-java-project/src/test/java/org/scribe/utils/OAuthEncoderTest.java b/src/main/resources/scribe-java-project/src/test/java/org/scribe/utils/OAuthEncoderTest.java new file mode 100644 index 0000000..cf986a2 --- /dev/null +++ b/src/main/resources/scribe-java-project/src/test/java/org/scribe/utils/OAuthEncoderTest.java @@ -0,0 +1,70 @@ +package org.scribe.utils; + +import org.junit.*; +import static org.junit.Assert.*; + +/** + * @author: Pablo Fernandez + */ +public class OAuthEncoderTest +{ + @Test + public void shouldPercentEncodeString() + { + String plain = "this is a test &^"; + String encoded = "this%20is%20a%20test%20%26%5E"; + assertEquals(encoded, OAuthEncoder.encode(plain)); + } + + @Test + public void shouldFormURLDecodeString() + { + String encoded = "this+is+a+test+%26%5E"; + String plain = "this is a test &^"; + assertEquals(plain, OAuthEncoder.decode(encoded)); + } + + @Test + public void shouldPercentEncodeAllSpecialCharacters() + { + String plain = "!*'();:@&=+$,/?#[]"; + String encoded = "%21%2A%27%28%29%3B%3A%40%26%3D%2B%24%2C%2F%3F%23%5B%5D"; + assertEquals(encoded, OAuthEncoder.encode(plain)); + assertEquals(plain, OAuthEncoder.decode(encoded)); + } + + @Test + public void shouldNotPercentEncodeReservedCharacters() + { + String plain = "abcde123456-._~"; + String encoded = plain; + assertEquals(encoded, OAuthEncoder.encode(plain)); + } + + @Test(expected = IllegalArgumentException.class) + public void shouldThrowExceptionIfStringToEncodeIsNull() + { + String toEncode = null; + OAuthEncoder.encode(toEncode); + } + + @Test(expected = IllegalArgumentException.class) + public void shouldThrowExceptionIfStringToDecodeIsNull() + { + String toDecode = null; + OAuthEncoder.decode(toDecode); + } + + @Test + public void shouldPercentEncodeCorrectlyTwitterCodingExamples() + { + // These tests are part of the Twitter dev examples here -> https://dev.twitter.com/docs/auth/percent-encoding-parameters + String sources[] = {"Ladies + Gentlemen", "An encoded string!", "Dogs, Cats & Mice"}; + String encoded[] = {"Ladies%20%2B%20Gentlemen", "An%20encoded%20string%21", "Dogs%2C%20Cats%20%26%20Mice"}; + + for(int i = 0; i < sources.length; i++) + { + Assert.assertEquals(encoded[i], OAuthEncoder.encode(sources[i])); + } + } +} diff --git a/src/main/resources/scribe-java-project/src/test/java/org/scribe/utils/PreconditionsTest.java b/src/main/resources/scribe-java-project/src/test/java/org/scribe/utils/PreconditionsTest.java new file mode 100644 index 0000000..84bc117 --- /dev/null +++ b/src/main/resources/scribe-java-project/src/test/java/org/scribe/utils/PreconditionsTest.java @@ -0,0 +1,87 @@ +package org.scribe.utils; + +import org.junit.*; + +public class PreconditionsTest +{ + + private static final String ERROR_MSG = ""; + + @Test(expected = IllegalArgumentException.class) + public void shouldThrowExceptionForNullObjects() + { + Preconditions.checkNotNull(null, ERROR_MSG); + } + + @Test(expected = IllegalArgumentException.class) + public void shouldThrowExceptionForNullStrings() + { + Preconditions.checkEmptyString(null, ERROR_MSG); + } + + @Test(expected = IllegalArgumentException.class) + public void shouldThrowExceptionForEmptyStrings() + { + Preconditions.checkEmptyString("", ERROR_MSG); + } + + @Test(expected = IllegalArgumentException.class) + public void shouldThrowExceptionForSpacesOnlyStrings() + { + Preconditions.checkEmptyString(" ", ERROR_MSG); + } + + @Test(expected = IllegalArgumentException.class) + public void shouldThrowExceptionForInvalidUrls() + { + Preconditions.checkValidUrl("this/is/not/a/valid/url", ERROR_MSG); + } + + @Test(expected = IllegalArgumentException.class) + public void shouldThrowExceptionForNullUrls() + { + Preconditions.checkValidUrl(null, ERROR_MSG); + } + + @Test + public void shouldAllowValidUrls() + { + Preconditions.checkValidUrl("http://www.example.com", ERROR_MSG); + } + + @Test + public void shouldAllowSSLUrls() + { + Preconditions.checkValidUrl("https://www.example.com", ERROR_MSG); + } + + @Test + public void shouldAllowSpecialCharsInScheme() + { + Preconditions.checkValidUrl("custom+9.3-1://www.example.com", ERROR_MSG); + } + + @Test + public void shouldAllowNonStandarProtocolsForAndroid() + { + Preconditions.checkValidUrl("x-url-custom://www.example.com", ERROR_MSG); + } + + @Test(expected = IllegalArgumentException.class) + public void shouldNotAllowStrangeProtocolNames() + { + Preconditions.checkValidUrl("$weird*://www.example.com", ERROR_MSG); + } + + @Test(expected = IllegalArgumentException.class) + public void shouldNotAllowUnderscoreInScheme() + { + Preconditions.checkValidUrl("http_custom://www.example.com", ERROR_MSG); + } + + @Test + public void shouldAllowOutOfBandAsValidCallbackValue() + { + Preconditions.checkValidOAuthCallback("oob", ERROR_MSG); + } +} diff --git a/src/main/resources/scribe-java-project/src/test/java/org/scribe/utils/StreamUtilsTest.java b/src/main/resources/scribe-java-project/src/test/java/org/scribe/utils/StreamUtilsTest.java new file mode 100644 index 0000000..976914d --- /dev/null +++ b/src/main/resources/scribe-java-project/src/test/java/org/scribe/utils/StreamUtilsTest.java @@ -0,0 +1,29 @@ +package org.scribe.utils; + +import java.io.ByteArrayInputStream; +import java.io.InputStream; + +import org.junit.Test; + +import static org.junit.Assert.*; + +public class StreamUtilsTest +{ + + @Test + public void shouldCorrectlyDecodeAStream() + { + String value = "expected"; + InputStream is = new ByteArrayInputStream(value.getBytes()); + String decoded = StreamUtils.getStreamContents(is); + assertEquals("expected", decoded); + } + + @Test(expected = IllegalArgumentException.class) + public void shouldFailForNullParameter() + { + InputStream is = null; + StreamUtils.getStreamContents(is); + fail("Must throw exception before getting here"); + } +}