Browse files

Added more scaladocs and a roadmap

added publish options for deploying to maven.
  • Loading branch information...
1 parent 352518d commit 2a5ea53b9d1edf878559d8a7a26e8b0f955aa8b8 @jesseeichar jesseeichar committed Feb 9, 2011
View
2 core/src/main/scala/scalax/io/Codec.scala
@@ -98,7 +98,7 @@ object Codec {
final val ISO8859:Codec = apply(Charset forName "ISO-8859-1")
final val UTF8:Codec = apply(Charset forName "UTF-8")
- def default = apply(Charset.defaultCharset)
+ def platformDefault = apply(Charset.defaultCharset)
def apply(encoding: String): Codec = new Codec(Charset forName encoding)
def apply(charSet: Charset): Codec = new Codec(charSet)
def apply(decoder: CharsetDecoder): Codec = {
View
85 core/src/main/scala/scalax/io/Input.scala
@@ -10,6 +10,9 @@ package scalax.io
import scala.collection.Traversable
import Line._
+import java.io.File
+import java.net.URL
+
/**
* An trait for objects that viewed as a sequence of bytes. For example InputStream
* and ReadableByteChannel could be an Input object.
@@ -113,15 +116,89 @@ trait Input {
object Input {
class AsInput(op: => Input) {
- /** Converts a Java collection to the corresponding Scala collection */
+ /** An object to an input object */
def asInput: Input = op
}
/**
- * Wrap a Traversable as an Input. Normally just Traversable[Int] and Traversable[Byte] are supported
+ * Wrap an arbitraty object as and AsInput object allowing the object to be converted to an Input object.
+ *
+ * The possible types of src are the subclasses of [[scalax.io.AsInputConverter]]
*/
- implicit def asInputConverter[B](src:B)(implicit converter:TraversableResourceConverter[B]) =
+ implicit def asInputConverter[B](src:B)(implicit converter:AsInputConverter[B]) =
new AsInput(converter.toInput(src))
+ /**
+ * Used by the [[scalax.io.Input]] object for converting an arbitrary object to an Input Object
+ *
+ * Note: this is a classic use of the type class pattern
+ */
+ trait AsInputConverter[-A] {
+ def toInput(t:A) : Input
+ }
+
+ /**
+ * contains several implementations of [[scalax.io.AsInputConverter]]. They will be implicitely resolved allowing
+ * a user of the library to simple call A.asInput and the converter will be found without the user needing to look up these classes
+ */
+ object AsInputConverter {
+
+ /**
+ * Converts a File to an Input object
+ */
+ implicit object FileConverter extends AsInputConverter[File]{
+ def toInput(file: File) = Resource.fromFile(file)
+ }
+ /**
+ * Converts a URL to an Input object
+ */
+ implicit object URLConverter extends AsInputConverter[URL]{
+ def toInput(url: URL) = Resource.fromURL(url)
+ }
+ /**
+ * Converts a Traversable of Ints to an Input object. Each Int is treated as a byte
+ */
+ implicit object TraversableIntsAsBytesConverter extends AsInputConverter[Traversable[Int]]{
+ def toInput(t: Traversable[Int]) = new Input {
+ def chars(implicit codec: Codec) = new LongTraversable[Char] {
+ val maxChars = codec.encoder.maxBytesPerChar
-}
+ lazy val chars = codec.decode(t.view.map{_.toByte}.toArray)
+ def foreach[U](f: (Char) => U) = chars.foreach(f)
+ }.view
+
+ def bytesAsInts = new LongTraversable[Int]{
+ def foreach[U](f: (Int) => U) = t.foreach(f)
+ }.view
+
+ def size = Some(t.size)
+ }
+ }
+ /**
+ * Converts a Traversable[Byte] to an Input object
+ */
+ implicit object TraversableByteConverter extends AsInputConverter[Traversable[Byte]]{
+ def toInput(t: Traversable[Byte]) = new Input {
+ def chars(implicit codec: Codec) = new LongTraversable[Char] {
+ val maxChars = codec.encoder.maxBytesPerChar
+
+ lazy val chars = codec.decode(t.toArray)
+ def foreach[U](f: (Char) => U) = chars.foreach(f)
+ }.view
+
+ def bytesAsInts = new LongTraversable[Int]{
+ def foreach[U](f: (Int) => U) = t.foreach(b => f(b.toInt))
+ }.view
+
+
+ override def bytes = new LongTraversable[Byte]{
+ def foreach[U](f: (Byte) => U) = t.foreach(b => f(b))
+ }.view
+
+ def size = Some(t.size)
+ }
+ }
+ }
+
+
+}
View
40 core/src/main/scala/scalax/io/Output.scala
@@ -10,7 +10,7 @@ package scalax.io
import resource._
import scala.collection.Traversable
-import java.io.{File => JFile, OutputStream}
+import java.io.{File, OutputStream}
/**
* A trait for objects that can have data written to them. For example an
@@ -102,3 +102,41 @@ trait Output {
underlyingOutput.writer.writeStrings(strings,separator)
}
}
+
+object Output {
+ class AsOutput(op: => Output) {
+ /** An object to an Output object */
+ def asOutput: Output = op
+ }
+
+ /**
+ * Wrap an arbitraty object as and AsOutput object allowing the object to be converted to an Output object.
+ *
+ * The possible types of src are the subclasses of [[scalax.io.AsOutputConverter]]
+ */
+ implicit def asOutputConverter[B](src:B)(implicit converter:AsOutputConverter[B]) =
+ new AsOutput(converter.toOutput(src))
+
+ /**
+ * Used by the [[scalax.io.Output]] object for converting an arbitrary object to an Output Object
+ *
+ * Note: this is a classic use of the type class pattern
+ */
+ trait AsOutputConverter[-A] {
+ def toOutput(t:A) : Output
+ }
+
+ /**
+ * contains several implementations of [[scalax.io.AsOutputConverter]]. They will be implicitely resolved allowing
+ * a user of the library to simple call A.asOutput and the converter will be found without the user needing to look up these classes
+ */
+ object AsOutputConverter {
+
+ /**
+ * Converts a File to an Output object
+ */
+ implicit object FileConverter extends AsOutputConverter[File]{
+ def toOutput(file: File) = Resource.fromFile(file)
+ }
+ }
+}
View
48 core/src/main/scala/scalax/io/ReadChars.scala
@@ -10,6 +10,8 @@ package scalax.io
import scala.collection.Traversable
import Line._
+import java.net.{URL, URLConnection}
+import java.io.File
/**
* An trait for objects that viewed as a sequence of characters. For example java.io.Reader
@@ -63,3 +65,49 @@ trait ReadChars {
def slurpString = chars.mkString
}
+
+
+object ReadChars {
+ class AsReadChars(op: Codec => ReadChars) {
+ /** An object to an ReadChars object */
+ def asReadChars(implicit codec:Codec): ReadChars = op(codec)
+ }
+
+ /**
+ * Wrap an arbitraty object as and AsReadChars object allowing the object to be converted to an ReadChars object.
+ *
+ * The possible types of src are the subclasses of [[scalax.io.AsReadCharsConverter]]
+ */
+ implicit def asReadCharsConverter[B](src:B)(implicit converter:AsReadCharsConverter[B]) =
+ new AsReadChars(codec => converter.toReadChars(src,codec))
+
+
+ /**
+ * Used by the [[scalax.io.ReadChars]] object for converting an arbitrary object to an ReadChars Object
+ *
+ * Note: this is a classic use of the type class pattern
+ */
+ trait AsReadCharsConverter[-A] {
+ def toReadChars(t:A,codec:Codec) : ReadChars
+ }
+
+ /**
+ * contains several implementations of [[scalax.io.AsReadCharsConverter]]. They will be implicitely resolved allowing
+ * a user of the library to simple call A.asReadChars and the converter will be found without the user needing to look up these classes
+ */
+ object AsReadCharsConverter {
+
+ /**
+ * Converts a File to an ReadChars object
+ */
+ implicit object FileConverter extends AsReadCharsConverter[File]{
+ def toReadChars(file: File, codec:Codec) = Resource.fromFile(file).reader(codec)
+ }
+ /**
+ * Converts a URL to an ReadChars object
+ */
+ implicit object URLConverter extends AsReadCharsConverter[URL]{
+ def toReadChars(url: URL, codec:Codec) = Resource.fromURL(url).reader(codec)
+ }
+ }
+}
View
1 core/src/main/scala/scalax/io/Resource.scala
@@ -526,6 +526,7 @@ object Resource {
* @return an InputStreamResource
*/
def fromURL(url:URL)(implicit extraCloser:CloseAction[InputStream]=Noop): InputStreamResource[InputStream] = fromInputStream(url.openStream)(extraCloser)
+
/**
* Converts the string to a URL and creates an Input Resource from the URL
*
View
39 core/src/main/scala/scalax/io/Seekable.scala
@@ -522,3 +522,42 @@ trait Seekable extends Input with Output {
}
}
}
+
+object Seekable {
+ class AsSeekable(op: => Seekable) {
+ /** An object to an Seekable object */
+ def asSeekable: Seekable = op
+ }
+
+ /**
+ * Wrap an arbitraty object as and AsSeekable object allowing the object to be converted to an Seekable object.
+ *
+ * The possible types of src are the subclasses of [[scalax.io.AsSeekableConverter]]
+ */
+ implicit def asSeekableConverter[B](src:B)(implicit converter:AsSeekableConverter[B]) =
+ new AsSeekable(converter.toSeekable(src))
+
+
+ /**
+ * Used by the [[scalax.io.Seekable]] object for converting an arbitrary object to an Seekable Object
+ *
+ * Note: this is a classic use of the type class pattern
+ */
+ trait AsSeekableConverter[-A] {
+ def toSeekable(t:A) : Seekable
+ }
+
+ /**
+ * contains several implementations of [[scalax.io.AsSeekableConverter]]. They will be implicitely resolved allowing
+ * a user of the library to simple call A.asSeekable and the converter will be found without the user needing to look up these classes
+ */
+ object AsSeekableConverter {
+
+ /**
+ * Converts a File to an Seekable object
+ */
+ implicit object FileConverter extends AsSeekableConverter[File]{
+ def toSeekable(file: File) = Resource.fromFile(file)
+ }
+ }
+}
View
77 core/src/main/scala/scalax/io/TraversableResourceConverter.scala
@@ -1,77 +0,0 @@
-package scalax.io
-
-import java.net.URL
-import java.io.{File, RandomAccessFile}
-
-/**
- * Used by the [[scalax.io.Input]] object for converting an arbitrary object to an Input Object
- *
- * Note: this is a classic use of the type class pattern
- */
-trait TraversableResourceConverter[-A] {
- def toInput(t:A) : Input
-}
-
-/**
- * contains several implementations of [[scalax.io.TraversableResourceConverter]]. They will be implicitely resolved allowing
- * a user of the library to simple call A.asInput and the converter will be found without the user needing to look up these classes
- */
-object TraversableResourceConverter {
-
- /**
- * Converts a File to an Input object
- */
- implicit object FileConverter extends TraversableResourceConverter[File]{
- def toInput(file: File) = Resource.fromFile(file)
- }
- /**
- * Converts a URL to an Input object
- */
- implicit object URLConverter extends TraversableResourceConverter[URL]{
- def toInput(url: URL) = Resource.fromURL(url)
- }
- /**
- * Converts a Traversable of Ints to an Input object. Each Int is treated as a byte
- */
- implicit object TraversableIntsAsBytesConverter extends TraversableResourceConverter[Traversable[Int]]{
- def toInput(t: Traversable[Int]) = new Input {
- def chars(implicit codec: Codec) = new LongTraversable[Char] {
- val maxChars = codec.encoder.maxBytesPerChar
-
- lazy val chars = codec.decode(t.view.map{_.toByte}.toArray)
- def foreach[U](f: (Char) => U) = chars.foreach(f)
- }.view
-
- def bytesAsInts = new LongTraversable[Int]{
- def foreach[U](f: (Int) => U) = t.foreach(f)
- }.view
-
- def size = Some(t.size)
- }
- }
- /**
- * Converts a Traversable[Byte] to an Input object
- */
- implicit object TraversableByteConverter extends TraversableResourceConverter[Traversable[Byte]]{
- def toInput(t: Traversable[Byte]) = new Input {
- def chars(implicit codec: Codec) = new LongTraversable[Char] {
- val maxChars = codec.encoder.maxBytesPerChar
-
- lazy val chars = codec.decode(t.toArray)
- def foreach[U](f: (Char) => U) = chars.foreach(f)
- }.view
-
- def bytesAsInts = new LongTraversable[Int]{
- def foreach[U](f: (Int) => U) = t.foreach(b => f(b.toInt))
- }.view
-
-
- override def bytes = new LongTraversable[Byte]{
- def foreach[U](f: (Byte) => U) = t.foreach(b => f(b))
- }.view
-
- def size = Some(t.size)
- }
- }
-}
-
View
120 core/src/main/scala/scalax/io/WriteChars.scala
@@ -10,12 +10,11 @@ package scalax.io
import resource._
import scala.collection.Traversable
-import java.io.Writer
-
+import java.io.{File, Writer}
/**
- * A trait for objects that can have data written to them. For example an
- * OutputStream and File can be an Output object (or be converted to one).
+ * A trait for objects that can have expect to have characters written to them. For example a
+ * FileWriter can be a WriteChars object (or be converted to one).
* <p>
* Note: Each invocation of a method will typically open a new stream or
* channel. That behaviour can be overridden by the implementation but
@@ -31,51 +30,94 @@ import java.io.Writer
*/
trait WriteChars {
- protected def writer : WriteCharsResource[Writer]
+ protected def writer : WriteCharsResource[Writer]
+
+ /**
+ * Write several characters to the underlying object
+ */
def write(characters : TraversableOnce[Char]) : Unit = {
for (out <- writer) {
characters foreach out.append
}
}
- /**
- * Writes a string. The open options that can be used are dependent
- * on the implementation and implementors should clearly document
- * which option are permitted.
- *
- * @param string
- * the data to write
- */
- def writeString(string : String) : Unit = {
- for (out <- writer) {
- out write string
+ /**
+ * Writes a string. The open options that can be used are dependent
+ * on the implementation and implementors should clearly document
+ * which option are permitted.
+ *
+ * @param string
+ * the data to write
+ */
+ def writeString(string : String) : Unit = {
+ for (out <- writer) {
+ out write string
+ }
+ }
+
+ /**
+ * Write several strings. The open options that can be used are dependent
+ * on the implementation and implementors should clearly document
+ * which option are permitted.
+ *
+ * @param strings
+ * The data to write
+ * @param separator
+ * A string to add between each string.
+ * It is not added to the before the first string
+ * or after the last.
+ */
+ def writeStrings(strings: Traversable[String], separator: String = ""): Unit = {
+ for (out <- writer) {
+ (strings foldLeft true) {
+ case (true, s) =>
+ out write s
+ false
+ case (false, s) =>
+ out write separator
+ out write s
+ false
}
}
+ }
+}
+
+object WriteChars {
+ class AsWriteChars(op: (Codec) => WriteChars) {
+ /** An object to an WriteChars object */
+ def asWriteChars(implicit codec:Codec): WriteChars = op(codec)
+ }
+
+ /**
+ * Wrap an arbitraty object as and AsWriteChars object allowing the object to be converted to an WriteChars object.
+ *
+ * The possible types of src are the subclasses of [[scalax.io.AsWriteCharsConverter]]
+ */
+ implicit def asWriteCharsConverter[B](src:B)(implicit converter:AsWriteCharsConverter[B]) =
+ new AsWriteChars(codec => converter.toWriteChars(src,codec))
+
+ /**
+ * Used by the [[scalax.io.WriteChars]] object for converting an arbitrary object to an WriteChars Object
+ *
+ * Note: this is a classic use of the type class pattern
+ */
+ trait AsWriteCharsConverter[-A] {
+ def toWriteChars(t:A,codec:Codec) : WriteChars
+ }
+
+ /**
+ * contains several implementations of [[scalax.io.AsWriteCharsConverter]]. They will be implicitely resolved allowing
+ * a user of the library to simple call A.asWriteChars and the converter will be found without the user needing to look up these classes
+ */
+ object AsWriteCharsConverter {
+
/**
- * Write several strings. The open options that can be used are dependent
- * on the implementation and implementors should clearly document
- * which option are permitted.
- *
- * @param strings
- * The data to write
- * @param separator
- * A string to add between each string.
- * It is not added to the before the first string
- * or after the last.
- */
- def writeStrings(strings : Traversable[String], separator : String = "") : Unit = {
- for (out <- writer) {
- (strings foldLeft true) {
- case (true, s) =>
- out write s
- false
- case (false, s) =>
- out write separator
- out write s
- false
- }
- }
+ * Converts a File to an WriteChars object
+ */
+ implicit object FileConverter extends AsWriteCharsConverter[File]{
+ def toWriteChars(file: File,codec:Codec) = Resource.fromFile(file).writer(codec)
}
+ }
}
View
5 core/src/main/scala/scalax/io/WriterOutputStream.scala
@@ -12,6 +12,11 @@ import java.io.{
OutputStream, Writer
}
+/**
+ * Takes a writer and allows it to be treated like a OutputStream, The data is encoded as it is written to the Writer
+ *
+ * '''Not API''' just a support class for implementation
+ */
protected[io] class WriterOutputStream(writer : Writer)( implicit codec : Codec) extends OutputStream {
private val encoding = codec.name
View
65 core/src/samples/asFooConverter.scala
@@ -0,0 +1,65 @@
+
+/**
+ * Examples for creating Output/Input/ReadChars/WriteChars etc... using the asFooConverter pattern.
+ *
+ * There are two patterns for creating IO objects. One is using the Resources API. This is often the best for
+ * creating resources from closeable objects such as InputStreams. The Resource API takes a code block for constructing
+ * the resource and can there for recreate the resource when needed.
+ *
+ * The other pattern is to convert an existing object to an Input/Ouput/ReadChars/WriteChars/Seekable object. The
+ * idea here is to import the implicit conversions contained in the target object (Input/Ouput/ReadChars/WriteChars/Seekable)
+ * and then call the asInput//Ouput/ReadChars/WriteChars/Seekable.
+ *
+ * Examples of the latter pattern are described here.
+ *
+ * Note: In all examples where a codec is required, the codec can be explicitly or implicitly passed
+ */
+object AsFooConverter {
+ /**
+ * Convert to Input
+ */
+ def asInput {
+ import scalax.io.Codec
+ import scalax.io.Input._
+
+ val webpage:String = new java.net.URL("http://www.scala-lang.org").asInput.slurpString(Codec.UTF8)
+ val bytes:Array[Byte] = List[Byte](1,2,3,4).asInput.byteArray
+ }
+ /**
+ * Convert to Output
+ */
+ def asOutput {
+ import scalax.io.Codec
+ import scalax.io.Output._
+
+ implicit val codec = Codec.UTF8
+
+ new java.io.File("io").asOutput.write("hi file")
+ }
+ /**
+ * Convert to Seekable
+ */
+ def asSeekable {
+ import scalax.io.Seekable._
+
+ new java.io.File("io").asSeekable.insert(2,List[Byte](1,2,3))
+ }
+ /**
+ * Convert to WriteChars
+ */
+ def asWriteChars {
+ import scalax.io.Codec
+ import scalax.io.WriteChars._
+
+ new java.io.File("io").asWriteChars(Codec.UTF8).write("This is a message in UTF8")
+ }
+ /**
+ * Convert to ReadChars
+ */
+ def asReadChars {
+ import scalax.io.Codec
+ import scalax.io.ReadChars._
+
+ val lines:Traversable[String] = new java.io.File("io").asReadChars(Codec.UTF8).lines()
+ }
+}
View
45 core/src/samples/output.scala
@@ -0,0 +1,45 @@
+import java.io.File
+
+/**
+ * One of the core IO classes is called Input. Normally the Input API will be encountered when a Resource object is
+ * created. But a resource is not required to have an Input object.
+ */
+object OutputExamples {
+ /**
+ * All Output resources extend the Output trait so the following operations can be used on any Output resource
+ * (ReadableByteChannel or OutputStream for example).
+ * <p>
+ * This example does not try to cover all operations since they are covered in multiple examples like in the
+ * basic-read-write examples.
+ * </p>
+ */
+ def basicOutput {
+ import scalax.io._
+
+ val output:Output = Resource.fromFileString("someFile")
+
+ output.writeIntsAsBytes(1,2,3)
+ output.write("hello")(Codec.UTF8)
+ output.writeStrings(List("hello","world")," ")(Codec.UTF8)
+ }
+
+ /**
+ * In addition to Resource.fromFoo methods to create Resources (which are often Output objects)
+ * There is a second option for converting certain objects directly to an Output object. This example
+ * shows how to convert a File to an output object
+ */
+ def convertObjectToOutput {
+ import scalax.io._
+ import java.io.File
+ import Output.asOutputConverter
+
+ // By default files can be converted to an Output Object by importing
+ // Output.asOutputConverter and calling asOutput on the file
+ val output:Output = new File("aFile").asOutput
+
+ // needed for the write call below
+ implicit val codec = Codec.UTF8
+
+ output.write("data is being written to file")
+ }
+}
View
20 core/src/samples/seekable.scala
@@ -85,6 +85,26 @@ object SeekableSamples {
}
/**
+ * In addition to Resource.fromFoo methods to create Resources (which are often Seekable objects)
+ * There is a second option for converting certain objects directly to an Seekable object. This example
+ * shows how to convert a File to an output object
+ */
+ def convertObjectToSeekable {
+ import scalax.io._
+ import java.io.File
+ import Seekable.asSeekableConverter
+
+ // By default files can be converted to an Seekable Object by importing
+ // Seekable.asSeekableConverter and calling asSeekable on the file
+ val seekable:Seekable = new File("aFile").asSeekable
+
+ // needed for the append and slurp calls below
+ implicit val codec = Codec.UTF8
+
+ seekable.append("data is being written to file")
+ val data:String = seekable.slurpString
+ }
+ /**
* Multiple Random accesses from a file opened only a single time
*/
def multipleAccesses {
View
2 project/build.properties
@@ -1,6 +1,6 @@
#Project properties
#Mon Apr 26 10:04:14 CEST 2010
-project.organization=org.scala-lang
+project.organization=com.github.scala-incubator.io
project.name=ScalaIO
sbt.version=0.7.4
project.version=0.1.0
View
17 project/build/ProjectSite.scala
@@ -1,7 +1,7 @@
-import sbt.Logger
+import sbt.{DefaultProject, Logger}
import xml.Node
-class ProjectSite(project:IoProject,log:Logger) {
+class ProjectSite(val project:DefaultProject with IoProject,log:Logger) {
val self = this;
val name = project.name
val summary = project.descSummary
@@ -14,8 +14,13 @@ class ProjectSite(project:IoProject,log:Logger) {
def navbar(site:WebsiteModel, currPage:ExamplesPage, relativeToBase:String,currEx:Option[Example], showAllProjects:Boolean):Node = {
<div id="navcontainer">
- <ul id="projectnavlist">{for(project <- site.projectSites) yield {
- <li><a href={relativeToBase+project.name+"/index.html"} title={project.summary} class={if(project == self)"active" else ""}>{project.name.capitalize}</a>
+ <ul id="projectnavlist">
+ <li><a href={relativeToBase+"/../index.html"}>Overview</a></li>
+ {for(project <- site.projectSites) yield {
+ <li><a href={relativeToBase+project.name+"/index.html"}
+ title={project.summary}
+ class={if(project == self)"active" else ""}>{project.name.capitalize}</a>
+ <a href={relativeToBase+"/"+project.name+"/scaladoc/index.html"}>(Scaladoc)</a>
{ if(project == self || showAllProjects) {
<ul id="navlist">{for(page <- project.pages) yield {
if(currPage == page ){
@@ -32,7 +37,9 @@ class ProjectSite(project:IoProject,log:Logger) {
}
}
</li>
- }}</ul>
+ }}
+ <li><a href={relativeToBase+"/../roadmap.html"}>Roadmap</a></li>
+ </ul>
</div>
}
View
152 project/build/ScalaIOProject.scala
@@ -1,8 +1,10 @@
import sbt._
import xml.Node
+import java.io._
class ScalaIOProject(info: ProjectInfo)
extends ParentProject(info) {
+
val mavenLocal = "Local Maven Repository" at "file://" + Path.userHome + "/.m2/repository"
val scalatoolsSnapshot = "Scala Tools Snapshot" at "http://scala-tools.org/repo-snapshots/"
val scalatoolsRelease = "Scala Tools Snapshot" at "http://scala-tools.org/repo-releases/"
@@ -11,10 +13,9 @@ class ScalaIOProject(info: ProjectInfo)
lazy val coreTest:TestProject = project("core-test", "core-test", new TestProject(_),core)
lazy val file:File = project("file", "file", new File(_),core)
lazy val fileTest:TestProject = project("file-test", "file-test", new TestProject(_),core,coreTest,file)
- lazy val archive:Archive = project("archive", "archive", new Archive(_),core, file)
+// lazy val archive:Archive = project("archive", "archive", new Archive(_),core, file)
lazy val webSite:WebSite = project("web-site", "web-site", new WebSite(_),core, file)
-
/* ------ Sub projects ------ */
class Core(info: ProjectInfo)
extends DefaultProject(info)
@@ -54,7 +55,7 @@ class ScalaIOProject(info: ProjectInfo)
}
class TestProject(info: ProjectInfo)
- extends DefaultProject(info) {
+ extends DefaultProject(info) with MavenPublishing {
val mockito = "org.mockito" % "mockito-all" % "1.8.0"
val junitInterface = "com.novocode" % "junit-interface" % "0.5"
@@ -111,31 +112,44 @@ class ScalaIOProject(info: ProjectInfo)
class WebSite(info:ProjectInfo)
extends DefaultProject(info) {
-
val siteOutput = outputPath / "site"
+ val siteZip = outputPath / "site.zip"
// Needed so that samples task for all project is executed before site
lazy val samples = task {None}
def siteTask = task {
val projectSites = dependencies flatMap {
- case project:IoProject => List(new ProjectSite(project,log))
+ case project:DefaultProject with IoProject => List(new ProjectSite(project,log))
case _ => Nil
}
siteOutput.asFile.mkdirs
FileUtilities.copy(mainResources.get, siteOutput, log)
+ projectSites.toList foreach { projectSite =>
+ val project = projectSite.project
+ val docs = project.mainDocPath
+
+ FileUtilities.copy((project.docPath / "main" / "api").##.***.get, siteOutput / projectSite.name / "scaladoc", log)
+ }
val site = new WebsiteModel(projectSites.toList,siteOutput,log)
site.buildSite
+
+ FileUtilities.zip(siteOutput.##.get,siteZip,true,log)
+
None
- } dependsOn samples
+ } dependsOn (samples,doc)
lazy val site = siteTask describedAs "Generate documentation web-site"
override protected def compileAction = task{None}
+/* val siteArtifact = Artifact(name+"-"+version, "zip", "zip")
+ override def artifacts = Set(siteArtifact)
+ override def packageToPublishActions = super.packageToPublishActions ++ Seq(site)*/
+
}
}
-trait IoProject extends AutoCompilerPlugins {
+trait IoProject extends AutoCompilerPlugins with MavenPublishing{
self : DefaultProject =>
override def documentOptions = super.documentOptions //++ List(CompoundDocOption("-doc-source-url","https://github.com/scala-incubator/scala-io/raw/master/"))
@@ -151,6 +165,8 @@ trait IoProject extends AutoCompilerPlugins {
def description:Iterable[Node]
def descSummary:String
+
+
override def compileOptions = super.compileOptions ++ List(
CompileOption("-P:continuations:enable"),
//CompileOption("-P:sxr:base-directory:" + mainScalaSourcePath.absolutePath),
@@ -191,3 +207,125 @@ trait IoProject extends AutoCompilerPlugins {
lazy val compileAll = compileSamples dependsOn (compile,testCompile)
}
+
+trait PackageToPublishActions {
+ self: TaskManager =>
+ def packageToPublishActions:Seq[Task]
+}
+trait MavenPublishing extends BasicScalaProject {
+ self: DefaultProject =>
+
+ // Publishing rules
+ override def managedStyle = ManagedStyle.Maven
+
+ // Choose the deployment location based on -SNAPSHOT in the version number
+ lazy val publishTo = if(version.toString.endsWith("-SNAPSHOT")) {
+ "nexus.scala-tools.org" at "http://nexus.scala-tools.org/content/repositories/snapshots/"
+ } else {
+ "nexus.scala-tools.org" at "http://nexus.scala-tools.org/content/repositories/releases/"
+ }
+
+ addMavenCredentialsForServer("nexus.scala-tools.org", "Sonatype Nexus Repository Manager")
+
+ def addMavenCredentialsForServer(serverId : String, name : String) {
+ try {
+ val user = System.getProperty(serverId+".user")
+ val password = System.getProperty(serverId+".pass")
+ if(user!=null) {
+ scala.Console.println("Registering credents on " + serverId + " for user " + user)
+ Credentials.add(name, serverId, user, password)
+ }
+ } catch {
+ case t => //Ignore errors, just log
+ scala.Console.println("Unable to load maven credentials for [" + serverId + "]")
+ }
+ }
+ override def packageDocsJar = defaultJarPath("-javadoc.jar")
+ override def packageSrcJar= defaultJarPath("-sources.jar")
+
+ lazy val sourceArtifact = Artifact.sources(artifactID)
+ lazy val docsArtifact = Artifact.javadoc(artifactID)
+ abstract override def packageToPublishActions = super.packageToPublishActions ++ Seq(packageDocs, packageSrc)
+ override def pomExtra =
+ <licenses>
+ <license>
+ <name>Scala License</name>
+ <url>http://www.scala-lang.org/node/146</url>
+ <distribution>repo</distribution>
+ </license>
+ </licenses>
+
+}
+trait ScalaBazaar {
+ self: DefaultProject =>
+ def outputBinPath = (outputPath ##) / "bin"
+
+ def ouputLibPath = (outputPath ##) / "lib"
+
+ def sbazName = name
+
+ def versionlessJarName = sbazName + ".jar"
+
+ def versionlessJarPath = ouputLibPath / versionlessJarName
+
+ def bazaarPackageName = sbazName + "-" + version + ".sbp"
+
+ def bazaarPackagePath = (outputPath ##) / bazaarPackageName
+
+ def bazaarAdvertName = sbazName + "-" + version + ".advert"
+
+ def bazaarAdvertPath = (outputPath ##) / bazaarAdvertName
+
+ def outputMetaPath = (outputPath ##) / "meta"
+
+ def descriptionPath = outputMetaPath / "description"
+
+ def outputDocPath = (outputPath ##) / "doc"
+
+ def bazaarDepends: List[String] = Nil
+
+ def description: String
+
+ def bazaarPackageBaseURL: String
+
+ lazy val sbazPack = sbazPackTask(bazaarDepends, Some(description))
+
+ def sbazPackTask(depends: List[String], description: Option[String]) = task {
+ if (!outputMetaPath.asFile.exists)
+ outputMetaPath.asFile.mkdir
+
+ val pack = <package>
+ <name>{sbazName}</name>
+ <version>{version}</version>{if (!depends.isEmpty)
+ <depends>{for (depend <- depends)
+ yield <name>{depend}</name>}</depends>
+ else
+ Nil}{if (!description.isEmpty)
+ <description>{description.get}</description>
+ else
+ Nil}</package>
+
+ val advert = <availablePackage>
+ {pack}
+ <link>{bazaarPackageBaseURL + bazaarPackageName}</link>
+ </availablePackage>
+
+ writeFile(descriptionPath.asFile, pack.toString)
+ writeFile(bazaarAdvertPath.asFile, advert.toString)
+
+ FileUtilities.zip(List(outputBinPath, ouputLibPath, outputDocPath, outputMetaPath),
+ bazaarPackagePath, true, log)
+ None
+ }.dependsOn(compile, doc)
+
+
+ private def writeFile(file: File, content: String) =
+ if (file.exists() && !file.canWrite())
+ error("File " + file + " is not writable")
+ else {
+ val writer = new FileWriter(file, false)
+ writer.write(content)
+ writer.close()
+ }
+}
+
View
107 project/build/WebiteModel.scala
@@ -31,12 +31,31 @@ class WebsiteModel(val projectSites:List[ProjectSite],val outputDir:Path,log:Log
val self = this;
def buildSite = {
Printer.printPage(outputDir / "index.html",indexHtml,log)
+ Printer.printPage(outputDir / "roadmap.html",roadmapHtml,log)
projectSites.foreach {
project=>
project.buildSite(self);
}
}
+ def navbar(overviewActive:Boolean) =
+ <div id="navcontainer">
+ <ul id="projectnavlist">
+ <li><a href="./index.html" class={if(overviewActive)"active" else ""}>Overview</a></li>
+ {for(project <- projectSites) yield {
+ <li><a href={project.name+"/index.html"}
+ title={project.summary}>{project.name.capitalize}</a> <a href={project.name+"/scaladoc/index.html"}>(Scaladoc)</a>
+ <ul id="navlist">
+ {for(page <- project.pages) yield {
+ <li><a title={page.uberSummaryText} href={project.pagePath(page)}>{page.name}</a></li>
+ }
+ }</ul>
+ </li>
+ }}
+ <li><a href="roadmap.html" class={if(!overviewActive)"active" else ""}>Roadmap</a></li>
+ </ul>
+ </div>
+
def indexHtml = {
val content =
<div class="explanation">
@@ -59,23 +78,95 @@ class WebsiteModel(val projectSites:List[ProjectSite],val outputDir:Path,log:Log
</p>
</div>
+
Template(false, "Scala IO API Documentation")(
<link href={"css/samples.css"} rel="stylesheet" type="text/css" ></link>)(
<h1>Scala IO API Documentation</h1>)(
- content)(
- <div id="navcontainer">
- <ul id="projectnavlist">{for(project <- projectSites) yield {
+ content)(navbar(true))
+ }
+
+ def roadmapHtml = {
+
+ def navbar(overviewActive:Boolean) = <div id="navcontainer">
+ <ul id="projectnavlist">
+ <li><a href="./index.html" class={if(overviewActive)"active" else ""}>Overview</a></li>
+ {for(project <- projectSites) yield {
<li><a href={project.name+"/index.html"}
- title={project.summary}>{project.name.capitalize}</a>
- <ul id="navlist">{
- for(page <- project.pages) yield {
+ title={project.summary}>{project.name.capitalize}</a> <a href={project.name+"/scaladoc/index.html"}>(Scaladoc)</a>
+ <ul id="navlist">
+ {for(page <- project.pages) yield {
<li><a title={page.uberSummaryText} href={project.pagePath(page)}>{page.name}</a></li>
}
}</ul>
</li>
- }}</ul>
- </div>)
+ }}
+ <li><a href="roadmap.html" class={if(!overviewActive)"active" else ""}>Roadmap</a></li>
+ </ul>
+ </div>
+ val roadmapContent =
+ <div class="explanation">
+ <strong>Scala IO Core</strong>
+ <p>Scala IO Core will be completed before much more work is done on the FS API so that the library
+ won't be forever being developed. In addition to the major items listed below the common task of
+ improving API and removing inconsistency will always be a focus. As will performance.</p>
+ <ol>
+ <li><strong>Large Data Integration Tests</strong>
+ <div>Create test sets that are very large (several GB) and verify that the operations can
+ handle the load and work correctly when skipping data</div>
+ </li>
+ <li><strong>Write Benchmark Tests</strong>
+ <div> Benchmark the integration tests as well as other types of operations (such as
+ large number of small requests on a large dataset).
+ <br/>
+ The idea is to track the performance of each version and ensure it continues to
+ increase each version (and by how much)
+ </div>
+ </li>
+ <li><strong>Add error handling to resources</strong>
+ <div>
+ At the moment unless a resource is used via Josh's ARM API an error reading from a
+ stream results in an exception being thrown. I want to allow a user to add an error
+ handler on the resource itself rather than having to use a catch block each time the
+ resource is used
+ </div>
+ </li>
+ <li><strong>Add Iteratee style IO processing</strong>
+ <div>
+ This is a very flexible way of handling IO with very good compositional properties
+ but for some (who are not familiar with the pattern) it can be less approachable
+ </div>
+ </li>
+ <li><strong>Add asynchronous callback style IO handling</strong>
+ <div>
+ This will appear much like that which is seen in NodeJS and will be implemented
+ based on the Iteratee IO processing
+ </div>
+ </li>
+ <li><strong>Implement Java 7 Implementations</strong>
+ <div>This may be raised in the list of priorities depending on how long each task takes.</div>
+ </li>
+ </ol>
+ <strong>Scala IO File</strong>
+ <ol>
+ <li><strong>Implement ZipFS</strong>
+ <div>
+ The goal is to have several different filesystem implementations that have different
+ characteristics to insure that the API is sufficiently flexible and, most importantly,
+ to make sure that the file system implementation API is flexible. The usage API is
+ design following NIO2 so I am fairly confident that has sufficient flexibility but the
+ implementer's API is also a very important API.
+ </div>
+ </li>
+ <li><strong>Implement based on Java 7</strong></li>
+ <li><strong>TBD...</strong></li>
+ </ol>
+ </div>
+
+ Template(false, "Scala IO Development Roadmap")(
+ <link href={"css/samples.css"} rel="stylesheet" type="text/css" ></link>)(
+ <h1>Scala IO Development Roadmap</h1>)(
+ roadmapContent)(navbar(false))
}
}

0 comments on commit 2a5ea53

Please sign in to comment.