当前位置: 首页>>代码示例>>Scala>>正文


Scala Enumerator类代码示例

本文整理汇总了Scala中play.api.libs.iteratee.Enumerator的典型用法代码示例。如果您正苦于以下问题:Scala Enumerator类的具体用法?Scala Enumerator怎么用?Scala Enumerator使用的例子?那么恭喜您, 这里精选的类代码示例或许可以为您提供帮助。


在下文中一共展示了Enumerator类的12个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的Scala代码示例。

示例1: Files

//设置package包名称以及导入依赖的类
package controllers

import java.io.FileInputStream
import java.util.UUID

import play.api.Play
import play.api.mvc.{Action, Controller, ResponseHeader, Result}
import com.google.common.io.BaseEncoding
import exceptions.GoogleAuthTokenExpired
import models.File
import play.api.libs.iteratee.Enumerator


object Files extends Controller {

  lazy val oauth2 = new utils.OAuth2(Play.current)

  def fileUpload = Action(parse.multipartFormData) { request =>
    request.body.file("file").map { picture =>
      val fileName = picture.filename
      val contentType = picture.contentType.getOrElse("text/html")
      val fstream = new FileInputStream(picture.ref.file)
      val ftext = BaseEncoding.base64.encode(Stream.continually(fstream.read).takeWhile(_ != -1).map(_.toByte).toArray)
      try {
        val user = oauth2.getUser(request.session)
        // Persist
        File.create(new File(0, user.id, fileName, contentType, ftext))
        // TODO(delyan): this should return file ID perhaps?
        Ok(fileName)
      } catch {
        case expired: GoogleAuthTokenExpired =>
          val state = UUID.randomUUID().toString
          Ok(views.html.index(None, Some(oauth2.getLoginURL(state)), List()))
            .withSession("oauth-state" -> state)
      }
    }.getOrElse {
      Redirect(routes.Users.index)
        .flashing("error" -> "Missing file")
    }
  }

  def file = Action {
    // TODO(delyan): File.get...
    Ok("{}").as("application/json")
  }

  def downloadFile(fileName: String) = Action { request =>
    val user = oauth2.getUser(request.session)
    val file = File.getByName(user.id, fileName)
    // TODO(delyan): File.get...
    val fileContent: Enumerator[Array[Byte]] = Enumerator(BaseEncoding.base64.decode(file.file))
    Result(
      header = ResponseHeader(200),
      body = fileContent
    ).as(file.content_type)
  }

} 
开发者ID:delqn,项目名称:botslandia,代码行数:59,代码来源:Files.scala

示例2: Assets

//设置package包名称以及导入依赖的类
package controllers.common

import play.api.mvc._
import play.api.libs.MimeTypes
import play.api.libs.iteratee.Enumerator
import play.api.http.{ DefaultHttpErrorHandler, ContentTypes }
import play.api.Configuration
import controllers.AssetsBuilder
import controllers.Assets.Asset
import scala.concurrent.Future
import scala.concurrent.ExecutionContext.Implicits.global
import java.io.File

class Assets(errorHandler: DefaultHttpErrorHandler) extends AssetsBuilder(errorHandler) {
  def public(path: String, file: Asset) = versioned(path, file)
  def lib(path: String, file: Asset) = versioned(path, file)
  def css(path: String, file: Asset) = versioned(path, file)
  def commonCss(path: String, file: Asset) = versioned(path, file)
  def js(path: String, file: Asset) = versioned(path, file)
  def commonJs(path: String, file: Asset) = versioned(path, file)
  def img(path: String, file: Asset) = versioned(path, file)
  def commonImg(path: String, file: Asset) = versioned(path, file)
}


abstract class SharedResources(errorHandler: DefaultHttpErrorHandler, conf: Configuration) extends Controller with utils.ConfigSupport {
  private lazy val path = confRequiredString("rsc.folder")

  def rsc(filename: String) = Action.async { implicit request =>
    {
      val file = new File(path + filename)
      if (file.exists() && file.isFile())
        Future.successful(Result(
          ResponseHeader(OK, Map(CONTENT_LENGTH -> file.length.toString, CONTENT_TYPE -> MimeTypes.forFileName(filename).getOrElse(ContentTypes.BINARY))),
          Enumerator.fromFile(file)
        ))
      else
        errorHandler.onClientError(request, NOT_FOUND, "File not found")
    }.recoverWith {
      case e => errorHandler.onServerError(request, new RuntimeException(s"Unexpected error while serving $filename at $path: " + e.getMessage, e))
    }
  }
} 
开发者ID:pawank,项目名称:play-silhouette-mongodb-multi-project-sbt,代码行数:44,代码来源:Assets.scala

示例3: FilesController

//设置package包名称以及导入依赖的类
package controllers.files

import java.text.SimpleDateFormat

import akka.stream.scaladsl.Source
import domain.storage.FileMeta
import play.api.libs.iteratee.Enumerator
import play.api.libs.json.Json
import play.api.libs.streams.Streams
import play.api.mvc._
import services.storage.{FileServices, FileTypeService}

import scala.concurrent.Future


class FilesController extends Controller {

  //  def upload = Action(parse.temporaryFile) { request =>
  //    request.body.moveTo(new File("/tmp/picture/uploaded"))
  //    Ok("File uploaded")
  //  }
  //curl -v -X POST http://localhost:9000/api/upload -F "[email protected]/home/hashcode/0imagescript/images/image.jpg"


  def upload = Action.async(parse.multipartFormData) { request =>
    import scala.concurrent.ExecutionContext.Implicits.global
    request.body.file("upload") match {
      case Some(file) => {
        val data = file.ref.file
        val meta = FileMeta(file.filename, FileTypeService.detectFile(data))
        val results = FileServices.processFile(data, meta)
        results map (result => {
          Ok(Json.toJson(result))
        })
      }
      case None => {
        Future {
          BadRequest
        }
      }
    }
  }

  def getFile(id: String, filename: String) = Action {
    import scala.concurrent.ExecutionContext.Implicits.global
    FileServices.getFile(id) match {
      case Some(file) => {
        val dataContent: Enumerator[Array[Byte]] = Enumerator.fromStream(file.inputStream)
        val source = Source.fromPublisher(Streams.enumeratorToPublisher(dataContent))
        Ok.chunked(source).as(file.contentType.getOrElse(BINARY))
      }
      case None => NotFound
    }
  }
} 
开发者ID:Thulebona,项目名称:hashpvtapi,代码行数:56,代码来源:FilesController.scala

示例4: ServerGateway

//设置package包名称以及导入依赖的类
package services

import javax.inject.Inject

import play.api.Configuration
import play.api.libs.iteratee.Enumerator
import play.api.libs.ws.WSClient
import play.api.mvc.Results.Status
import play.api.mvc.{ResponseHeader, Result}

import scala.concurrent.Future

object ServerGateway

class ServerGateway @Inject()(configuration: Configuration) {

  implicit val context = play.api.libs.concurrent.Execution.Implicits.defaultContext

  def forwardRequestToServer(request: ProxyRequest, ws: WSClient): Future[Result] = {
    val wsRequest = ws.url(request.uri.toString)
      .withHeaders(request.simpleHeaderMap.toList: _*)
      .withMethod(request.method)
      .withBody(request.httpMessage.body.getOrElse(""))
      .withRequestTimeout(configuration.getLong("server.timeout").getOrElse(60000))

    wsRequest.execute().map { response =>
      def responseHeader = toSimpleHeaderMap(response.allHeaders)
      responseHeader.get("Transfer-Encoding") match {
        case Some("chunked") =>
          new Status(response.status)
            .chunked(Enumerator(response.bodyAsBytes))
            .withHeaders(responseHeader.toList: _*)
        case default =>
          val headers =
            responseHeader map {
              // fix the "Content-Lenght" header manually
              h => (h._1, if (h._1 == "Content-Length")
                response.body.toString
              else h._2.head)
            }
          Result(ResponseHeader(response.status, responseHeader), Enumerator(response.bodyAsBytes))

      }


    }

  }

  private def toSimpleHeaderMap(headers: Map[String, Seq[String]]): Map[String, String] = {
    headers.map {
      case (k, v) => (k, v.mkString(","))
    }
  }

} 
开发者ID:innoq,项目名称:docster,代码行数:57,代码来源:ServerGateway.scala

示例5: Widgets

//设置package包名称以及导入依赖的类
package controllers.util

import play.api.libs.iteratee.Enumerator
import de.fuberlin.wiwiss.silk.runtime.task.TaskStatus
import play.api.libs.Comet
import play.api.libs.json._
import play.api.libs.concurrent.Execution.Implicits._

object Widgets {
  val log = java.util.logging.Logger.getLogger(getClass.getName)

  def taskStatus(stream: Enumerator[TaskStatus], id: String = "") = {
    def serializeStatus(status: TaskStatus): JsValue = {
      JsObject(
        ("id" -> JsString(id)) ::
        ("progress" -> JsNumber(status.progress * 100.0)) ::
        ("message" -> JsString(status.toString)) ::
        ("failed" -> JsBoolean(status.failed)) :: Nil
      )
    }
    stream.map(serializeStatus) &> Comet(callback = "parent.updateStatus")
  }

  def autoReload(reloadFunc: String, stream: Enumerator[_]) = {
    stream.map(_ => "") &> Comet(callback = "parent." + reloadFunc)
  }
} 
开发者ID:petrovskip,项目名称:silk.2.6-GenLinkSA,代码行数:28,代码来源:Widgets.scala

示例6: HomeController

//设置package包名称以及导入依赖的类
package controllers

import java.io.OutputStream
import javax.inject._

import akka.stream.scaladsl.{Source, StreamConverters}
import play.api._
import play.api.libs.iteratee.Enumerator
import play.api.libs.streams.Streams
import play.api.mvc._

import scala.concurrent.ExecutionContext.Implicits.global

@Singleton
class HomeController @Inject() extends Controller {

  def index = Action {
    val source = brokenSource
    Ok.chunked(source).as("text/plain")
  }

  private def brokenSource = StreamConverters.asOutputStream().mapMaterializedValue(write)

  private def workingSource = {
    val enumerator = Enumerator.outputStream(write)
    Source.fromPublisher(Streams.enumeratorToPublisher(enumerator))
  }

  def write(out: OutputStream) {
    try {
      val bytes = ("*" * 1024).getBytes
      out.write(bytes)
    } finally {
      out.flush()
      out.close()
    }
  }

} 
开发者ID:halfninja,项目名称:play-outputstream-bug,代码行数:40,代码来源:HomeController.scala

示例7: ScoreFilter

//设置package包名称以及导入依赖的类
package filters

import play.api.libs.iteratee.Enumerator
import play.api.mvc.{ Result, RequestHeader, Filter }
import play.api.libs.concurrent.Execution.Implicits._

import scala.concurrent.Future


class ScoreFilter extends Filter {

  override def apply(nextFilter: (RequestHeader) => Future[Result])(rh: RequestHeader): Future[Result] = {

    val result = nextFilter(rh)

    result.map { res =>
      if (res.header.status == 200 || res.header.status == 406) {
        val correct = res.session(rh).get("correct").getOrElse(0)
        val wrong = res.session(rh).get("wrong").getOrElse(0)
        val score = s"\nYour current score is: $correct correct answers and $wrong wrong answers"
        val newBody = res.body andThen Enumerator(score.getBytes("UTF-8"))
        res.copy(body = newBody)
      } else {
        res
      }
    }
  }
} 
开发者ID:chibariyo,项目名称:simpleVocabularyTeacher,代码行数:29,代码来源:ScoreFilter.scala

示例8: EnumController

//设置package包名称以及导入依赖的类
package controllers

import javax.inject.Inject
import akka.actor.ActorSystem
import akka.stream.scaladsl.{Source}
import play.api.libs.iteratee.Enumerator
import play.api.libs.streams.Streams
import play.api.mvc._
import scala.concurrent.Future
import scala.concurrent.duration._
import scala.concurrent.ExecutionContext.Implicits.global

class EnumController @Inject() (actorSystem: ActorSystem) extends Controller {

  def index = Action {
    val source = Source.single("Hello World\n")
    Ok.chunked(source)
  }


  def inf1 = Action {
    val source = Source.fromFuture(Future.successful("YES"))
    Ok.chunked(source)
  }

  def inf2 = Action {
    val source = Source.unfoldAsync()(size => {
      val data: Future[String] = akka.pattern.after(500 millis, actorSystem.scheduler)(Future("hello\n"))
      data.map(contents => Some(size, contents))
    })
    Ok.chunked(source)
  }

  def inf3 = Action {
    val source = Source.tick(0 millisecond, 500 millisecond, "hello\n")
    Ok.chunked(source)
  }

  def compose = Action {
    val hello = Enumerator("hello\n")
    val bye = Enumerator("good bye\n")
    val body = hello.andThen(bye)
    Ok.chunked(Source.fromPublisher(Streams.enumeratorToPublisher(body)))
  }


  def inf4 = Action {
    val hello = Enumerator.generateM({akka.pattern.after(500 millis, actorSystem.scheduler)(Future(Some("helllo\n")))})
    val bye = Enumerator.generateM(akka.pattern.after(2000 millis, actorSystem.scheduler)(Future(Some("bye\n"))))
    val body = Enumerator.interleave(hello, bye)
    val response = Source.fromPublisher(Streams.enumeratorToPublisher(body))
    Ok.chunked(response)
  }


} 
开发者ID:LittleWizard,项目名称:exp-play,代码行数:57,代码来源:EnumController.scala

示例9: url

//设置package包名称以及导入依赖的类
package jp.co.bizreach.trace.play24

import java.io.IOException
import javax.inject.Inject

import jp.co.bizreach.trace.{TraceData, ZipkinTraceServiceLike}
import play.api.libs.iteratee.Enumerator
import play.api.libs.ws._

import scala.concurrent.Future


  def url(spanName: String, url: String)(implicit traceData: TraceData): WSRequest = {
    new TraceWSRequest(spanName, ws.url(url), tracer, traceData)
  }

  @scala.throws[IOException]
  def close(): Unit = ws.close()

  private class TraceWSRequest(spanName: String, request: WSRequest, tracer: ZipkinTraceServiceLike, traceData: TraceData) extends WSRequest {

    override val url: String = request.url
    override val method: String = request.method
    override val body: WSBody = request.body
    override val headers: Map[String, Seq[String]] = request.headers
    override val queryString: Map[String, Seq[String]] = request.queryString
    override val calc: Option[WSSignatureCalculator] = request.calc
    override val auth: Option[(String, String, WSAuthScheme)] = request.auth
    override val followRedirects: Option[Boolean] = request.followRedirects
    override val requestTimeout: Option[Int] = request.requestTimeout
    override val virtualHost: Option[String] = request.virtualHost
    override val proxyServer: Option[WSProxyServer] = request.proxyServer

    override def sign(calc: WSSignatureCalculator): WSRequest = new TraceWSRequest(spanName, request.sign(calc), tracer, traceData)
    override def withAuth(username: String, password: String, scheme: WSAuthScheme): WSRequest = new TraceWSRequest(spanName, request.withAuth(username, password, scheme), tracer, traceData)
    override def withHeaders(hdrs: (String, String)*): WSRequest = new TraceWSRequest(spanName, request.withHeaders(hdrs:_*), tracer, traceData)
    override def withQueryString(parameters: (String, String)*): WSRequest = new TraceWSRequest(spanName, request.withQueryString(parameters:_*), tracer, traceData)
    override def withFollowRedirects(follow: Boolean): WSRequest = new TraceWSRequest(spanName, request.withFollowRedirects(follow), tracer, traceData)
    override def withRequestTimeout(timeout: Long): WSRequest = new TraceWSRequest(spanName, request.withRequestTimeout(timeout), tracer, traceData)
    override def withVirtualHost(vh: String): WSRequest = new TraceWSRequest(spanName, request.withVirtualHost(vh), tracer, traceData)
    override def withProxyServer(proxyServer: WSProxyServer): WSRequest = new TraceWSRequest(spanName, request.withProxyServer(proxyServer), tracer, traceData)
    override def withBody(body: WSBody): WSRequest = new TraceWSRequest(spanName, request.withBody(body), tracer, traceData)
    override def withMethod(method: String): WSRequest = new TraceWSRequest(spanName, request.withMethod(method), tracer, traceData)

    override def execute(): Future[WSResponse] = tracer.traceWS(spanName, traceData){ span =>
      request.withHeaders(tracer.toMap(span).toSeq: _*).execute()
    }
    override def stream(): Future[(WSResponseHeaders, Enumerator[Array[Byte]])] = tracer.traceWS(spanName, traceData){ span =>
      request.withHeaders(tracer.toMap(span).toSeq: _*).stream()
    }
  }
} 
开发者ID:bizreach,项目名称:play-zipkin-tracing,代码行数:53,代码来源:TraceWSClient.scala

示例10: url

//设置package包名称以及导入依赖的类
package jp.co.bizreach.trace.play23

import jp.co.bizreach.trace.TraceData
import play.api.Application
import play.api.libs.iteratee.Enumerator
import play.api.libs.ws._

import scala.concurrent.Future


  def url(spanName: String, url: String)(implicit app: Application, traceData: TraceData): play.api.libs.ws.WSRequestHolder = {
    new TraceWSRequest(spanName, WS.url(url), traceData)
  }

  private class TraceWSRequest(spanName: String, request: WSRequestHolder, traceData: TraceData) extends WSRequestHolder {
    override val url: String = request.url
    override val method: String = request.method
    override val body: WSBody = request.body
    override val headers: Map[String, Seq[String]] = request.headers
    override val queryString: Map[String, Seq[String]] = request.queryString
    override val calc: Option[WSSignatureCalculator] = request.calc
    override val auth: Option[(String, String, WSAuthScheme)] = request.auth
    override val followRedirects: Option[Boolean] = request.followRedirects
    override val requestTimeout: Option[Int] = request.requestTimeout
    override val virtualHost: Option[String] = request.virtualHost
    override val proxyServer: Option[WSProxyServer] = request.proxyServer

    override def sign(calc: SignatureCalculator): WSRequestHolder = new TraceWSRequest(spanName, request.sign(calc), traceData)
    override def withAuth(username: String, password: String, scheme: WSAuthScheme): WSRequestHolder = new TraceWSRequest(spanName, request.withAuth(username, password, scheme), traceData)
    override def withHeaders(hdrs: (String, String)*): WSRequestHolder = new TraceWSRequest(spanName, request.withHeaders(hdrs:_*), traceData)
    override def withQueryString(parameters: (String, String)*): WSRequestHolder = new TraceWSRequest(spanName, request.withQueryString(parameters:_*), traceData)
    override def withFollowRedirects(follow: Boolean): WSRequestHolder = new TraceWSRequest(spanName, request.withFollowRedirects(follow), traceData)
    override def withRequestTimeout(timeout: Int): WSRequestHolder = new TraceWSRequest(spanName, request.withRequestTimeout(timeout), traceData)
    override def withVirtualHost(vh: String): WSRequestHolder = new TraceWSRequest(spanName, request.withVirtualHost(vh), traceData)
    override def withProxyServer(proxyServer: WSProxyServer): WSRequestHolder = new TraceWSRequest(spanName, request.withProxyServer(proxyServer), traceData)
    override def withBody(body: WSBody): WSRequestHolder = new TraceWSRequest(spanName, request.withBody(body), traceData)
    override def withMethod(method: String): WSRequestHolder = new TraceWSRequest(spanName, request.withMethod(method), traceData)
    override def execute(): Future[Response] = ZipkinTraceService.traceWS(spanName, traceData){ span =>
      request.withHeaders(ZipkinTraceService.toMap(span).toSeq:_*).execute()
    }
    override def stream(): Future[(WSResponseHeaders, Enumerator[Array[Byte]])] = ZipkinTraceService.traceWS(spanName, traceData){ span =>
      request.withHeaders(ZipkinTraceService.toMap(span).toSeq:_*).stream()
    }
  }

} 
开发者ID:bizreach,项目名称:play-zipkin-tracing,代码行数:47,代码来源:TraceWS.scala

示例11: StreamController

//设置package包名称以及导入依赖的类
package controllers

import javax.inject.{Inject, Named}

import actors.ScoreStreamer
import actors.StreamActor.Start
import actors.TournamentEventActor.SetChannel
import akka.actor.ActorRef
import akka.util.Timeout
import play.api.libs.json.JsObject
import play.api.mvc.{Action, Controller}

import scala.concurrent.duration._
import akka.stream.scaladsl.Source
import play.api.libs.EventSource
import play.api.libs.iteratee.{Concurrent, Enumerator}
import play.api.libs.streams.Streams

import scala.concurrent.ExecutionContext.Implicits.global

class StreamController @Inject()(@Named("score-streamer") scoreStreamer: ActorRef, @Named("stream-actor") streamActor: ActorRef, @Named("tournament-event-actor") tournamentEventActor: ActorRef) extends Controller {
  implicit val timeout = Timeout(5 seconds)

  val (out, channel) = Concurrent.broadcast[JsObject]
  streamActor ! Start(channel)

  val (scoreOut, scoreChanel) = Concurrent.broadcast[JsObject]
  scoreStreamer ! ScoreStreamer.Start(scoreChanel)

  tournamentEventActor ! SetChannel(streamActor)

  def tournamentEventStream = Action { implicit req => enumeratorToStream(out)}

  def scoreEventStream = Action { implicit req => enumeratorToStream(scoreOut)}

  private def enumeratorToStream(enumerator: Enumerator[JsObject]) = {
    val source: Source[String, Any] = Source.fromPublisher(Streams.enumeratorToPublisher(enumerator.map(x => x.toString())))
    Ok.chunked(source via EventSource.flow).as("text/event-stream")
  }
} 
开发者ID:koenvanloock,项目名称:whifwhat,代码行数:41,代码来源:StreamController.scala

示例12: AuthKey

//设置package包名称以及导入依赖的类
package jp.t2v.lab.play2.auth

import de.frosner.broccoli.conf
import de.frosner.broccoli.controllers.AuthConfigImpl
import de.frosner.broccoli.models.Anonymous
import de.frosner.broccoli.services.SecurityService
import de.frosner.broccoli.util.Logging
import jp.t2v.lab.play2.stackc.{RequestAttributeKey, RequestWithAttributes, StackableController}
import play.api.libs.iteratee.{Enumerator, Iteratee}

import scala.concurrent.ExecutionContext.Implicits.global
import play.api.mvc._

import scala.concurrent.Future

trait BroccoliWebsocketSecurity extends AsyncAuth with AuthConfigImpl with Logging {

  self: Controller with AuthConfig =>

  val securityService: SecurityService

  private[auth] case object AuthKey extends RequestAttributeKey[User]

  def withSecurity[A](req: RequestHeader)(
      f: (Option[AuthenticityToken], User, RequestHeader) => (Iteratee[A, _], Enumerator[A]))
    : Future[Either[Result, (Iteratee[A, _], Enumerator[A])]] =
    securityService.authMode match {
      case conf.AUTH_MODE_CONF =>
        val maybeToken = extractToken(req)
        val tokenString = maybeToken.getOrElse("<session ID missing>")
        val maybeUser = restoreUser(req, scala.concurrent.ExecutionContext.Implicits.global)
        maybeUser
          .recover {
            case exception =>
              Logger.info(s"Authenticating the following session failed (session probably outdated): $tokenString") // TODO log level
              (None, identity[Result] _) // don't follow IntelliJ's recommendation here!
          }
          .flatMap {
            // TODO do we need the updater here? can we even use cookies or should we authenticate for each new WS connection?
            case (Some(user), updater) =>
              Logger.info(s"Successfully authenticated session $tokenString of $user") // TODO log level
              Future.successful(Right(f(maybeToken, user, req)))
            case (None, _) =>
              Logger.info(s"Websocket to ${req.remoteAddress} not established because of missing authentication") // TODO log level
              authenticationFailed(req).map(result => Left(result))
          }
      case conf.AUTH_MODE_NONE =>
        Future.successful(Right(f(None, Anonymous, req)))
      case other => throw new IllegalStateException(s"Unrecognized auth mode: ${securityService.authMode}")
    }

  implicit def loggedIn(implicit req: RequestWithAttributes[_]): User = securityService.authMode match {
    case conf.AUTH_MODE_CONF => req.get(AuthKey).get
    case conf.AUTH_MODE_NONE => Anonymous.asInstanceOf[User]
    case other               => throw new IllegalStateException(s"Unrecognized auth mode: ${securityService.authMode}")
  }

} 
开发者ID:FRosner,项目名称:cluster-broccoli,代码行数:59,代码来源:BroccoliWebsocketSecurity.scala


注:本文中的play.api.libs.iteratee.Enumerator类示例由纯净天空整理自Github/MSDocs等开源代码及文档管理平台,相关代码片段筛选自各路编程大神贡献的开源项目,源码版权归原作者所有,传播和使用请参考对应项目的License;未经允许,请勿转载。