Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP

Loading…

Accepting java parameters on controllers without conversion to java.lang.String #13

Merged
merged 1 commit into from

4 participants

@gregoriokusowski

By checking the parent of each instance variable class on the controller, we can
be sure if it's a Rjb::Rjb_JavaClass or Rjb::Rjb_JavaProxy instance.
Example cases like Rjb::Java_lang_String or Rjb::Java_util_HashMap will also be
as they are.
I'm not sure if we can receive a Rjb::Rjb_JavaBridge, but it will work too.

The example present on the specs shows how java parameters can be used.

    title = (Rjb::import 'java.lang.String').new("The Beatles")
    @parameter_that_is_a_java_class = (Rjb::import 'java.util.HashMap').new
    @parameter_that_is_a_java_class.put("title", title)
<parameter name="parameter_that_is_a_java_class" class="java.util.Map"/>
...
<textFieldExpression><![CDATA[$P{parameter_that_is_a_java_class}.get("title")]]></textFieldExpression>

I chose to not convert every Hash to a java.util.HashMap because it can grow up easily if we use a recursive approach. I'll add later a snippet to the wiki or readme with a simple conversion tool.
Improvements and suggestions will be appreciated.

@gregoriokusowski gregoriokusowski Accepting java parameters on controllers without conversion to java.l…
…ang.String.

By checking the parent of each instance variable class on the controller, we can
be sure if it's a Rjb::Rjb_JavaClass or Rjb::Rjb_JavaProxy instance.
Example cases like Rjb::Java_lang_String or Rjb::Java_util_HashMap will also be
as they are.
I'm not sure if we can receive a Rjb::Rjb_JavaBridge, but it will work too.
c7896d8
@msaraiva msaraiva merged commit acd4161 into fortesinformatica:master
@msaraiva
Owner

This solves issue #12.

Thanks Kusowski!

@plentz

I was talking with @gregoriokusowski earlier today and we discussed that this isn't really the best solution for the user. we thought in iterating over all controller's instance variables(ignoring those with @_ since it's used by rails[1] - something like what is done here), and checking class types - if it's an array or an hash, we convert to java's corresponding type, everything else is passed as a string(as it's done today). that way, the user will be able to use

@my_hash = {baz: "zinga!"}
@my_array = ["A","B","C", "easy as", 1, 2, 3, "or simple as", "do re mi"]

which we think is way better then the solution explained in the initial post. what you guys think? cc @msaraiva @rodrigomaia

[1]

1.9.3p327 :002 > x = FooController.new
1.9.3p327 :003 > x.instance_variables
 => [:@_routes, :@_action_has_layout, :@_headers, :@_status, :@_request, :@_response]
@msaraiva
Owner

I don't like the idea of having any Java related code in the controllers. I will probably not use it. But the feature itself is nice. Whatever solution we find to convert the data from ruby to java must face the problem of recursion and custom types. So I agree we should have a solution that convert arrays and hashes automatically (we just need to define how deep in the structure). That will cover the 95% of all the use. However, we can keep the current solution in case the user find himself among the other 5%.
It sounds reasonable. Right?

@plentz

@msaraiva 100% agree. So we try to do our best converting ruby objects to java and if we can't the user still have the workaround.

About the deepness, any suggestion? I can't imagine a case where we can't go all the way in all the levels that the object have, since we're going to do it just in the current controller instance variables. Am I right?

@ionosphere
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Commits on Nov 20, 2012
  1. @gregoriokusowski

    Accepting java parameters on controllers without conversion to java.l…

    gregoriokusowski authored
    …ang.String.
    
    By checking the parent of each instance variable class on the controller, we can
    be sure if it's a Rjb::Rjb_JavaClass or Rjb::Rjb_JavaProxy instance.
    Example cases like Rjb::Java_lang_String or Rjb::Java_util_HashMap will also be
    as they are.
    I'm not sure if we can receive a Rjb::Rjb_JavaBridge, but it will work too.
This page is out of date. Refresh to see the latest.
View
18 README.md
@@ -46,9 +46,9 @@ Note: This list will become your datasource inside the report.
2) Create your jasper report source file using iReport or any compatible jasper tool.
-3) Set the "Query Text" and "The language for the dataset query" properties of your report.
+3) Set the "Query Text" and "The language for the dataset query" properties of your report.
-Note: If you're using iReport, you can find those properties in the "Properties panel".
+Note: If you're using iReport, you can find those properties in the "Properties panel".
Don't forget to select the report root node in your "Report inspector".
Example: If you have a list of people, you should have something like:
@@ -60,7 +60,7 @@ Example: If you have a list of people, you should have something like:
5) Save the report source file in your views folder (just like any other html view file):
Example:
-
+
* app/views/people/index.jrxml
## Parameters
@@ -78,7 +78,7 @@ Example:
All you have to do now is to create, in iReport, a parameter called "user" (yes, without the "@") and drop it in your report!
-Limitation: By now, all parameters are converted to java String. We intend to change this in the near future.
+Limitation: By now, all parameters that aren't manually converted to Rjb java classes/instances are converted to java String. We intend to change this in the near future.
## RSpec integration
Check out: [jasper-rails-rspec](http://github.com/fortesinformatica/jasper-rails-rspec).
@@ -88,14 +88,14 @@ For a running example, just clone: [jasper-rails-demo](http://github.com/fortesi
## History
This project was first developed at Grupo Fortes in 2011 and we have been using it in several projects since then.
-Pay attention that all the features it supports right now were based in those project's especific needs. Therefore you might find a lot of
-JasperResports' features that are not yet supported.
-
+Pay attention that all the features it supports right now were based in those project's especific needs. Therefore you might find a lot of
+JasperResports' features that are not yet supported.
+
## LICENSE
Copyright (C) 2012 Marlus Saraiva, Rodrigo Maia
-Permission is hereby granted, free of charge, to any person obtaining
+Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
@@ -108,7 +108,7 @@ included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
View
46 lib/jasper-rails.rb
@@ -1,20 +1,20 @@
-#
+#
# Copyright (C) 2012 Marlus Saraiva, Rodrigo Maia
-#
-# Permission is hereby granted, free of charge, to any person obtaining
+#
+# Permission is hereby granted, free of charge, to any person obtaining
# a copy of this software and associated documentation files (the
# "Software"), to deal in the Software without restriction, including
# without limitation the rights to use, copy, modify, merge, publish,
# distribute, sublicense, and/or sell copies of the Software, and to
# permit persons to whom the Software is furnished to do so, subject to
# the following conditions:
-#
+#
# The above copyright notice and this permission notice shall be
# included in all copies or substantial portions of the Software.
-#
+#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
@@ -30,7 +30,7 @@
end
module JasperRails
-
+
class << self
attr_accessor :config
end
@@ -39,7 +39,7 @@ class << self
Dir["#{File.dirname(__FILE__)}/java/*.jar"].each do |jar|
classpath << File::PATH_SEPARATOR + File.expand_path(jar)
end
-
+
Dir["lib/*.jar"].each do |jar|
classpath << File::PATH_SEPARATOR + File.expand_path(jar)
end
@@ -67,14 +67,13 @@ class << self
self.config = {
:report_params=>{
"REPORT_LOCALE" => Locale.new('en', 'US'),
- "XML_LOCALE" => Locale.new('en', 'US'),
+ "XML_LOCALE" => Locale.new('en', 'US'),
"XML_DATE_PATTERN" => 'yyy-MM-dd'
}
}
-
+
module Jasper
module Rails
-
def self.render_pdf(jasper_file, datasource, parameters, options)
options ||= {}
parameters ||= {}
@@ -86,11 +85,12 @@ def self.render_pdf(jasper_file, datasource, parameters, options)
JasperRails.config[:report_params].each do |k,v|
jasper_params.put(k, v)
end
-
- # Convert the ruby parameters' hash to a java HashMap.\
- # Pay attention that, for now, all parameters are converted to string!
- parameters.each do |k,v|
- jasper_params.put(JavaString.new(k.to_s), JavaString.new(v.to_s))
+
+ # Convert the ruby parameters' hash to a java HashMap, but keeps it as
+ # default when they already represent a JRB entity.
+ # Pay attention that, for now, all other parameters are converted to string!
+ parameters.each do |key, value|
+ jasper_params.put(JavaString.new(key.to_s), parameter_value_of(value))
end
# Compile it, if needed
@@ -106,7 +106,7 @@ def self.render_pdf(jasper_file, datasource, parameters, options)
# This is here to avoid the "already initialized constant DOCUMENT_POSITION_*" warnings.
JRXmlUtils._invoke('parse', 'Lorg.xml.sax.InputSource;', input_source)
end
-
+
jasper_params.put(JRXPathQueryExecuterFactory.PARAMETER_XML_DATA_DOCUMENT, data_document)
jasper_print = JasperFillManager.fillReport(jasper_file, jasper_params)
else
@@ -125,6 +125,18 @@ def self.render_pdf(jasper_file, datasource, parameters, options)
raise e
end
end
+
+ # Returns the value without conversion when it's converted to Java Types.
+ # When isn't a Rjb class, returns a Java String of it.
+ def self.parameter_value_of(param)
+ # Using Rjb::import('java.util.HashMap').new, it returns an instance of
+ # Rjb::Rjb_JavaProxy, so the Rjb_JavaProxy parent is the Rjb module itself.
+ if param.class.parent == Rjb
+ param
+ else
+ JavaString.new(param.to_s)
+ end
+ end
end
end
View
60 spec/controllers/people_controller_spec.rb
@@ -1,79 +1,89 @@
require 'spec_helper'
describe PeopleController do
-
+
describe "GET index" do
before do
Person.stub(:all).and_return([
- Person.new(:name=>'john' , :email=>'lennon@beatles.com'),
+ Person.new(:name=>'john' , :email=>'lennon@beatles.com'),
Person.new(:name=>'george', :email=>'harrison@beatles.com')
])
end
-
+
it "should respond success" do
get :index, :format => :pdf
-
+
response.should be_success
end
-
+
it "should not contain nulls" do
get :index, :format => :pdf
-
+
response.should_not contain("null")
end
it "should show all fields in the report" do
get :index, :format => :pdf
-
+
response.should contain("john")
response.should contain("lennon@beatles.com")
response.should contain("george")
response.should contain("harrison@beatles.com")
end
-
+
it "should clip the text if it's larger than the Text Field" do
Person.stub(:all).and_return([
- Person.new(:name=>'jonh' , :email=>'a_very_long_text_that_is_larger_than_the_text_field_in_the_report')
+ Person.new(:name=>'jonh' , :email=>'a_very_long_text_that_is_larger_than_the_text_field_in_the_report')
])
-
+
get :index, :format => :pdf
-
+
response.should_not contain("a_very_long_text_that_is_larger_than_the_text_field_in_the_report")
response.should contain("a_very_long_text_that_is_larger_than_the_text_field_in_the_")
end
-
+
it "should show the parameters defined in the controller" do
get :index, :format => :pdf
-
+
response.should contain("I'm a parameter. I was defined in the controller")
end
end
-
+
describe "GET compile_time_error_report" do
-
+
it "should raise a RuntimeError if the report's design is not valid" do
expect { get :compile_time_error_report, :format => :pdf }.to raise_error(RuntimeError, /Report design not valid/)
end
-
+
end
-
+
describe "GET runtime_error_report" do
-
+
it "should raise a RuntimeError if the report could not be filled due to a runtime error" do
expect { get :runtime_error_report, :format => :pdf }.to raise_error(RuntimeError)
end
-
+
end
-
+
describe "GET nil_datasource" do
-
+
it "should treat nil datasources" do
get :nil_datasource, :format => :pdf
-
+
response.should contain("I'm a parameter. I was defined in the controller")
end
-
+
+ end
+
+ describe "GET java_parameter" do
+
+ it "accepts java parameter without converting it to string" do
+ get :java_parameter, :format => :pdf
+
+ response.should contain("The Beatles")
+ end
+
end
-
-end
+
+end
View
18 spec/internal/app/controllers/people_controller.rb
@@ -3,17 +3,17 @@ class PeopleController < ActionController::Base
def index
@people = Person.all
-
+
@parameter_defined_in_the_controller = "I'm a parameter. I was defined in the controller"
-
+
respond_with @people
end
- def compile_time_error_report
+ def compile_time_error_report
respond_with []
end
-
- def runtime_error_report
+
+ def runtime_error_report
respond_with []
end
@@ -22,4 +22,12 @@ def nil_datasource
respond_with nil
end
+ def java_parameter
+ title = (Rjb::import 'java.lang.String').new("The Beatles")
+ @parameter_that_is_a_java_class = (Rjb::import 'java.util.HashMap').new
+ @parameter_that_is_a_java_class.put("title", title)
+
+ respond_with nil
+ end
+
end
View
118 spec/internal/app/views/people/java_parameter.jrxml
@@ -0,0 +1,118 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<jasperReport xmlns="http://jasperreports.sourceforge.net/jasperreports" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://jasperreports.sourceforge.net/jasperreports http://jasperreports.sourceforge.net/xsd/jasperreport.xsd" name="index" language="groovy" pageWidth="595" pageHeight="842" columnWidth="535" leftMargin="20" rightMargin="20" topMargin="20" bottomMargin="20" uuid="311ea5a2-cc66-43bf-9af3-b2e0a552b1de">
+ <property name="ireport.zoom" value="1.0"/>
+ <property name="ireport.x" value="0"/>
+ <property name="ireport.y" value="0"/>
+ <style name="Title" forecolor="#FFFFFF" fontName="Arial" fontSize="26" isBold="true" pdfFontName="Helvetica-Bold"/>
+ <style name="SubTitle" forecolor="#666666" fontName="Arial" fontSize="18"/>
+ <style name="Column header" forecolor="#666666" fontName="Arial" fontSize="12" isBold="true"/>
+ <style name="Detail" fontName="Arial" fontSize="12"/>
+ <parameter name="parameter_that_is_a_java_class" class="java.util.Map"/>
+ <queryString language="xPath">
+ <![CDATA[/people/person]]>
+ </queryString>
+ <field name="name" class="java.lang.String">
+ <fieldDescription><![CDATA[name]]></fieldDescription>
+ </field>
+ <field name="email" class="java.lang.String">
+ <fieldDescription><![CDATA[email]]></fieldDescription>
+ </field>
+ <background>
+ <band splitType="Stretch"/>
+ </background>
+ <title>
+ <band height="70" splitType="Stretch">
+ <image>
+ <reportElement uuid="0b15b501-e65d-4f8b-b890-759a6d279efe" x="-20" y="0" width="595" height="64"/>
+ <imageExpression><![CDATA["wood.jpg"]]></imageExpression>
+ </image>
+ <staticText>
+ <reportElement uuid="dfeee47e-d32e-4525-a708-7cc3d6ec3f91" style="Title" x="0" y="5" width="263" height="33"/>
+ <textElement verticalAlignment="Middle"/>
+ <text><![CDATA[jasper-rails]]></text>
+ </staticText>
+ <textField>
+ <reportElement uuid="91699025-171b-40b4-ae45-eb9cdca69b2b" x="97" y="38" width="358" height="20" forecolor="#FFFFFF"/>
+ <textElement>
+ <font size="15"/>
+ </textElement>
+ <textFieldExpression><![CDATA[$P{parameter_that_is_a_java_class}.get("title")]]></textFieldExpression>
+ </textField>
+ </band>
+ </title>
+ <pageHeader>
+ <band splitType="Stretch"/>
+ </pageHeader>
+ <columnHeader>
+ <band height="36" splitType="Stretch">
+ <line>
+ <reportElement uuid="6a63817d-d338-4966-9432-96e7baffc7f8" positionType="FixRelativeToBottom" x="0" y="35" width="555" height="1"/>
+ <graphicElement>
+ <pen lineWidth="0.5" lineColor="#999999"/>
+ </graphicElement>
+ </line>
+ <staticText>
+ <reportElement uuid="89d037e3-230c-4845-b0aa-a43920c60dc2" x="48" y="15" width="100" height="20"/>
+ <textElement/>
+ <text><![CDATA[name]]></text>
+ </staticText>
+ <staticText>
+ <reportElement uuid="6920786b-3719-4243-bee2-9e4073274cb1" x="245" y="15" width="100" height="20"/>
+ <textElement/>
+ <text><![CDATA[email]]></text>
+ </staticText>
+ </band>
+ </columnHeader>
+ <detail>
+ <band height="21" splitType="Stretch">
+ <textField>
+ <reportElement uuid="63d9b6a9-caa5-40d8-8bb0-41822dd43364" x="48" y="0" width="185" height="20"/>
+ <textElement/>
+ <textFieldExpression><![CDATA[$F{name}]]></textFieldExpression>
+ </textField>
+ <textField>
+ <reportElement uuid="83b41533-c6ed-4de6-8c48-5545c9c78e43" x="245" y="0" width="290" height="20"/>
+ <textElement/>
+ <textFieldExpression><![CDATA[$F{email}]]></textFieldExpression>
+ </textField>
+ </band>
+ </detail>
+ <columnFooter>
+ <band height="45" splitType="Stretch">
+ <line>
+ <reportElement uuid="9642b713-530f-4d6e-a4dd-b6e7b4d07e2b" positionType="FixRelativeToBottom" x="0" y="3" width="555" height="1"/>
+ <graphicElement>
+ <pen lineWidth="0.5" lineColor="#999999"/>
+ </graphicElement>
+ </line>
+ </band>
+ </columnFooter>
+ <pageFooter>
+ <band height="20" splitType="Stretch">
+ <textField>
+ <reportElement uuid="06b23f1b-7ac0-4c70-bb2e-2aeb039f67a3" style="Column header" x="433" y="0" width="80" height="20"/>
+ <textElement textAlignment="Right">
+ <font size="10" isBold="false"/>
+ </textElement>
+ <textFieldExpression><![CDATA["Page "+$V{PAGE_NUMBER}+" of"]]></textFieldExpression>
+ </textField>
+ <textField evaluationTime="Report">
+ <reportElement uuid="b8b7868e-fe9c-4e1b-8a24-75b97450ef73" style="Column header" x="513" y="0" width="40" height="20"/>
+ <textElement>
+ <font size="10" isBold="false"/>
+ </textElement>
+ <textFieldExpression><![CDATA[" " + $V{PAGE_NUMBER}]]></textFieldExpression>
+ </textField>
+ <textField pattern="EEEEE dd MMMMM yyyy">
+ <reportElement uuid="f924a532-c0df-4366-baad-4126ffb1462f" style="Column header" x="0" y="0" width="197" height="20"/>
+ <textElement>
+ <font size="10" isBold="false"/>
+ </textElement>
+ <textFieldExpression><![CDATA[new java.util.Date()]]></textFieldExpression>
+ </textField>
+ </band>
+ </pageFooter>
+ <summary>
+ <band splitType="Stretch"/>
+ </summary>
+</jasperReport>
View
1  spec/internal/config/routes.rb
@@ -4,6 +4,7 @@
get 'compile_time_error_report'
get 'runtime_error_report'
get 'nil_datasource'
+ get 'java_parameter'
end
end
end
Something went wrong with that request. Please try again.