rack-xslview 0.1.3 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
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