Module: environment-reports Author: Andy Armstrong Copyright: Original Code is Copyright (c) 1995-2004 Functional Objects, Inc. All rights reserved. License: Functional Objects Library Public License Version 1.0 Dual-license: GNU Lesser General Public License Warranty: Distributed WITHOUT WARRANTY OF ANY KIND /// Report protocol define constant $report-width = 72; define constant $report-separator = make(, size: $report-width, fill: '-'); define constant = one-of(#"text", #"html", #"xml"); define abstract class () sealed constant slot report-format :: = #"text", init-keyword: format:; end class ; define abstract class () slot report-directory :: false-or() = #f, init-keyword: directory:; end class ; define sealed domain make (subclass()); define sealed domain initialize (); define generic write-report-as (stream :: , report :: , format :: ) => (); define generic create-multi-file-report-as (report :: , locator :: , format :: ) => (root-filename :: false-or()); /// Some useful report subclasses define abstract class () sealed constant slot report-project :: , required-init-keyword: project:; end class ; /// Implementation define class () keyword format-string: = "unsupported report options"; end class ; define method write-report-as (stream :: , report :: , format :: ) => () error(make()); end method write-report-as; define function write-report (stream :: , report :: ) => () write-report-as(stream, report, report.report-format) end function write-report; define function create-multi-file-report (report :: , directory :: ) => (root-filename :: false-or()) create-multi-file-report-as(report, directory, report.report-format) end function create-multi-file-report; define function create-report-to-string (report :: ) => (string :: ) with-output-to-string (stream) let format = report.report-format; write-report-as(stream, report, format) end end function create-report-to-string; /// Installation define constant $reports = make(); define class () sealed constant slot report-info-name :: , required-init-keyword: name:; sealed constant slot report-info-class :: subclass(), required-init-keyword: class:; sealed constant slot report-info-title :: , required-init-keyword: title:; sealed constant slot report-info-edition :: = #"basic", init-keyword: edition:; sealed constant slot report-info-formats :: = #[#"text"], init-keyword: formats:; sealed constant slot report-info-multi-file? :: = #f, init-keyword: multi-file?:; end class ; define function report-info-format-name (info :: , format :: ) => (name :: ) //---*** Make this extensible... select (format) #"text" => "Text"; #"html" => "HTML"; #"xml" => "XML"; end end function report-info-format-name; define function available-reports () => (reports :: ) let reports :: = make(); for (report :: in $reports) if (release-contains-edition?(report.report-info-edition)) add!(reports, report) end end; reports end function available-reports; define function install-report (name :: , title :: , class :: subclass(), #rest args, #key, #all-keys) => () element($reports, name) := apply(make, , name: name, title: title, class: class, args) end function install-report; define function find-report-info (name :: ) => (info :: false-or()) element($reports, name, default: #f) end function find-report-info;