rack-xslview 0.1.3 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/Rakefile CHANGED
@@ -7,19 +7,19 @@ begin
7
7
  gem.name = "rack-xslview"
8
8
  gem.summary = %Q{XSL rack middleware.}
9
9
  gem.description = %Q{A rack middleware for transforming XML with XSL.}
10
- gem.email = "albert.lash@docunext.com"
11
- gem.homepage = "http://www.docunext.com/wiki/Rack-XSLView"
12
- gem.authors = ["Albert Lash"]
13
- gem.rubyforge_project = ""
14
- gem.add_development_dependency "shoulda"
10
+ gem.email = 'albert.lash@docunext.com'
11
+ gem.homepage = 'http://www.docunext.com/wiki/Rack-XSLView'
12
+ gem.authors = ['Albert Lash']
13
+ gem.rubyforge_project = ''
14
+ gem.add_development_dependency 'shoulda'
15
15
  # gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
16
16
  end
17
17
  Jeweler::GemcutterTasks.new
18
18
  Jeweler::RubyforgeTasks.new do |rubyforge|
19
- rubyforge.doc_task = "rdoc"
19
+ rubyforge.doc_task = 'rdoc'
20
20
  end
21
21
  rescue LoadError
22
- puts "Jeweler (or a dependency) not available. Install it with: sudo gem install jeweler"
22
+ puts 'Jeweler (or a dependency) not available. Install it with: sudo gem install jeweler'
23
23
  end
24
24
 
25
25
 
@@ -46,6 +46,7 @@ end
46
46
  task :test => :check_dependencies
47
47
 
48
48
  task :default => :test
49
+ task :spec => :test
49
50
 
50
51
  require 'rake/rdoctask'
51
52
  Rake::RDocTask.new do |rdoc|
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.1.3
1
+ 0.2.0
data/lib/rack-xslview.rb CHANGED
@@ -1,12 +1,16 @@
1
- # MIT License
1
+ # Copyright 2010 Savonix Corporation
2
+ # Author Albert L. Lash, IV
3
+ # License MIT
2
4
  module Rack
3
5
  class XSLView
6
+
7
+ class XSLViewError < StandardError ; end
8
+
4
9
  def initialize(app, options)
5
- @my_path_info = String.new
6
10
  @app = app
7
- @myhash = {}
8
11
  @options = {:myxsl => nil}.merge(options)
9
- if @options[:myxsl] == nil
12
+ if @options[:myxsl].nil?
13
+ require 'rexml/document'
10
14
  @xslt = XML::XSLT.new()
11
15
  @xslt.xsl = REXML::Document.new '<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns="http://www.w3.org/1999/xhtml"><xsl:import href="http://github.com/docunext/1bb02b59/raw/master/standard.html.xsl"/><xsl:output method="xml" encoding="UTF-8" omit-xml-declaration="no" doctype-system="http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd" doctype-public="-//W3C//DTD XHTML 1.0 Transitional//EN" indent="yes"/></xsl:stylesheet>'
12
16
  else
@@ -15,44 +19,73 @@ module Rack
15
19
  end
16
20
 
17
21
  def call(env)
18
- if checknoxsl(env)
19
- @app.call(env)
20
- else
21
- if @options[:reload] == true
22
- puts @options[:filepath]
23
- @xslt = XML::XSLT.new()
24
- @xslt.xsl = REXML::Document.new @options[:xslfile]
25
- end
26
- unless @options[:passenv] == nil
27
- @options[:passenv].each { |envkey|
28
- if (mp = env[envkey])
29
- @myhash[envkey] = "#{mp}"
30
- end
31
- }
32
- @xslt.parameters = @myhash
33
- end
34
- status, headers, body = @app.call(env)
22
+ # No matter what, @app will be called
23
+ status, headers, body = @app.call(env)
35
24
 
36
- # Obtain entire request body
37
- parts = ''
38
- body.each { |part| parts << part.to_s }
25
+ # If setup includes paths to exclude from xslt processing, check them
26
+ checknoxsl(env) if @options[:noxsl]
39
27
 
40
- # TODO Refactor
41
- if ((parts.include? "<html") || !(parts.include? "<"))
42
- [status, headers, body]
43
- else
44
- headers.delete('Content-Length')
45
- @xslt.xml = parts
46
- newbody = []
47
- newbody << @xslt.serve
48
- headers['Content-Length'] = newbody[0].length.to_s
49
- [status, headers, newbody]
50
- end
28
+ # Obtain entire request body, check to make sure it can be processed
29
+ myxml = getResponse(body)
30
+
31
+ # Should XSL file be reloaded?
32
+ if @options[:reload] == true
33
+ @xslt = XML::XSLT.new()
34
+ @xslt.xsl = REXML::Document.new @options[:xslfile]
51
35
  end
36
+
37
+ # Set XML for stylesheet
38
+ @xslt.xml = myxml
39
+
40
+ # If setup includes env vars to pass through as params, do so
41
+ unless @options[:passenv].nil?
42
+ @myhash = {}
43
+ @options[:passenv].each { |envkey|
44
+ # Does env var exist?
45
+ @myhash[envkey] = "#{env[envkey]}" if env[envkey]
46
+ }
47
+ @xslt.parameters = @myhash unless @myhash.empty?
48
+ end
49
+
50
+ # Perform the transformation
51
+ newbody = Array.[](@xslt.serve)
52
+
53
+ # If we've made it this far, we can alter the headers
54
+ headers.delete('Content-Length')
55
+ headers['Content-Length'] = newbody[0].length.to_s
56
+ [status, headers, newbody]
57
+
58
+ rescue XSLViewError
59
+ # TODO Logging: "Rack XSLView not processed" if env['RACK_ENV'] == 'development'
60
+ [status, headers, body]
52
61
  end
53
62
 
54
63
  private
64
+ def checknoxsl(env)
65
+ @options[:noxsl].each { |path|
66
+ raise XSLViewError if env["PATH_INFO"].index(path)
67
+ }
68
+ end
69
+ def getResponse(body)
70
+ raise XSLViewError if body.nil?
71
+ newbody = ''
72
+ body.each { |part|
73
+ # Only check the first chunk to ensure 1) its not HTML and 2) its XML
74
+ checkForXml(part) if newbody.empty?
75
+ newbody << part.to_s
76
+ }
77
+ return newbody
78
+ end
79
+ def checkForXml(x)
80
+ # Abort processing if content cannot be processed by libxslt
81
+ raise XSLViewError unless x[0,1] == '<'
82
+ if @options[:excludehtml] == true
83
+ raise XSLViewError if x.include? '<html'
84
+ end
85
+ end
86
+
55
87
  def choosesheet(env)
88
+ # Not used yet, this may be used to match stylesheets with paths
56
89
  @options[:xslhash].each_key { |path|
57
90
  if env["PATH_INFO"].index(path)
58
91
  return @options[:xslhash][path]
@@ -60,14 +93,6 @@ module Rack
60
93
  }
61
94
  return false
62
95
  end
63
- def checknoxsl(env)
64
- @options[:noxsl].each { |path|
65
- if env["PATH_INFO"].index(path)
66
- return true
67
- end
68
- }
69
- return false
70
- end
71
96
  end
72
97
  end
73
98
 
@@ -8,6 +8,7 @@ class RackXslviewTest < Test::Unit::TestCase
8
8
 
9
9
  end
10
10
 
11
+
11
12
  def self.should_not_halt
12
13
  should "not halt the rack chain" do
13
14
  @app.expects(:call).once
@@ -15,6 +16,15 @@ class RackXslviewTest < Test::Unit::TestCase
15
16
  end
16
17
  end
17
18
 
19
+ def self.should_be_a_rack_response
20
+ should 'be a rack a response' do
21
+ ret = @rack.call(call_args)
22
+ assert ret.is_a?(Array), 'return value is not a valid rack response'
23
+ assert_equal 3, ret.size, 'should have 3 arguments'
24
+ end
25
+ end
26
+
27
+
18
28
  context 'Given an app' do
19
29
  setup do
20
30
  @app = Class.new { def call(app); true; end }.new
@@ -26,6 +36,7 @@ class RackXslviewTest < Test::Unit::TestCase
26
36
  passenv = ['PATH_INFO', 'RACK_MOUNT_PATH']
27
37
  @rack = Rack::XSLView.new(@app, :noxsl => omitpaths, :passenv => passenv)
28
38
  }
39
+ should_be_a_rack_response
29
40
  should_not_halt
30
41
  end
31
42
  context 'Trying out the xslhash' do
@@ -35,7 +46,7 @@ class RackXslviewTest < Test::Unit::TestCase
35
46
  xslhash.default("/path/to/output.xhtml10.xsl")
36
47
  @rack = Rack::XSLView.new(@app, :noxsl => omitpaths, :xslhash => xslhash)
37
48
  }
38
- should_not_halt
49
+ should_be_a_rack_response
39
50
  end
40
51
  end
41
52
  end
data/test/test_install.rb CHANGED
@@ -1,2 +1 @@
1
- require 'rubygems'
2
- require 'rack-xslview'
1
+
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rack-xslview
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.3
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Albert Lash
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2010-03-03 00:00:00 -05:00
12
+ date: 2010-03-20 00:00:00 -04:00
13
13
  default_executable:
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency