Failed Conditions
Push — master ( 9531b6...8da191 )
by Sébastien
07:33
created

JasperCompileManager::compileReport()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 8
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 4
CRAP Score 3.3332

Importance

Changes 0
Metric Value
dl 0
loc 8
ccs 4
cts 6
cp 0.6667
rs 9.4285
c 0
b 0
f 0
cc 3
eloc 6
nc 3
nop 1
crap 3.3332
1
<?php
2
3
declare(strict_types=1);
4
5
/*
6
 * Jasper report integration for PHP
7
 *
8
 * @link      https://github.com/belgattitude/soluble-jasper
9
 * @author    Vanvelthem Sébastien
10
 * @copyright Copyright (c) 2017 Vanvelthem Sébastien
11
 * @license   MIT
12
 */
13
14
namespace Soluble\Jasper\Proxy\Engine;
15
16
use Soluble\Japha\Bridge\Adapter as BridgeAdapter;
17
use Soluble\Japha\Bridge\Exception\JavaException;
18
use Soluble\Japha\Interfaces\JavaClass;
19
use Soluble\Japha\Interfaces\JavaObject;
20
use Soluble\Jasper\Exception;
21
use Soluble\Jasper\Proxy\RemoteJavaObjectProxyInterface;
22
23
class JasperCompileManager implements RemoteJavaObjectProxyInterface
24
{
25
    /**
26
     * @var BridgeAdapter
27
     */
28
    private $ba;
29
30
    /**
31
     * @var JavaClass Java('net.sf.jasperreports.engine.JasperCompileManager')
32
     */
33
    private $compileManager;
34
35 27
    public function __construct(BridgeAdapter $bridgeAdapter)
36
    {
37 27
        $this->ba = $bridgeAdapter;
38 27
    }
39
40
    /**
41
     * Compile the jrxml report file in a faster binary format.
42
     *
43
     * @return JavaObject Java('net.sf.jasperreports.engine.JasperReport')
44
     *
45
     * @throws Exception\BrokenXMLReportFileException when cannot parse the xml content or invalid xml file
46
     * @throws Exception\ReportFileNotFoundException  when the report file cannot be located (both php and java sides)
47
     * @throws Exception\ReportCompileException       when there's an error compiling/evaluating the report
48
     * @throws Exception\JavaProxiedException         when the compileReport has encountered a Java error
49
     * @throws Exception\RuntimeException             when an unexpected problem have been encountered
50
     */
51 26
    public function compileReport(string $reportFile): JavaObject
52
    {
53
        try {
54 26
            return $this->getJavaProxiedObject()->compileReport($reportFile);
55 7
        } catch (JavaException $e) {
56 7
            throw $this->getCompileManagerJavaException($e, $reportFile);
57
        } catch (\Throwable $e) {
58
            throw new Exception\RuntimeException($e->getMessage(), $e->getCode(), $e);
59
        }
60
    }
61
62
    /**
63
     * Compile the jrxml report file in a file.
64
     *
65
     * @throws Exception\InvalidArgumentException     when the source and dest are the same file
66
     * @throws Exception\BrokenXMLReportFileException when cannot parse the xml content or invalid xml file
67
     * @throws Exception\ReportFileNotFoundException  when the report file cannot be located (both php and java sides)
68
     * @throws Exception\ReportCompileException       when there's an error compiling/evaluating the report
69
     * @throws Exception\JavaProxiedException         when the compileReport has encountered a Java error
70
     * @throws Exception\RuntimeException             when an unexpected problem have been encountered
71 7
     */
72
    public function compileReportToFile(string $sourceFile, string $destFile): void
73 7
    {
74
        if (!file_exists($sourceFile)) {
75 7
            throw new Exception\ReportFileNotFoundException(
76 7
                sprintf(
77 7
                    'Report file %s does not exists',
78 7
                    $sourceFile
79 2
                )
80 1
            );
81 1
        }
82 1
83
        if (basename($sourceFile) === basename($destFile)) {
84
            throw new Exception\InvalidArgumentException(
85 1
                sprintf(
86 1
                    'Source and destination file names must be different (source: %s, dest: %s)',
87 2
                    $sourceFile,
88
                    $destFile
89
                    )
90 5
            );
91 4
        }
92 4
93 4
        try {
94
            $this->getJavaProxiedObject()->compileReportToFile($sourceFile, $destFile);
95 1
        } catch (JavaException $e) {
96 1
            throw $this->getCompileManagerJavaException($e, $sourceFile);
97 1
        } catch (\Throwable $e) {
98 1
            throw new Exception\RuntimeException($e->getMessage(), $e->getCode(), $e);
99
        }
100
    }
101
102
    /**
103 7
     * Return mapped exception from jasper compile manager java:.
104
     *
105
     * Exception\BrokenXMLReportFileException        when cannot parse the xml content or invalid xml file
106
     * Exception\ReportFileNotFoundException         when the report file is not found
107 7
     * Exception\ReportFileNotFoundFromJavaException when the report file is not found from the java side
108
     * Exception\ReportCompileException              when there's an error compiling/evaluating the report
109
     * Exception\JavaProxiedException                when the compileReport has encountered a Java error
110
     */
111
    private function getCompileManagerJavaException(JavaException $e, string $reportFile): Exception\ExceptionInterface
112
    {
113
        $exception = null;
114
115 27
        $className = $e->getJavaClassName();
116
        if ($className === 'net.sf.jasperreports.engine.JRException') {
117 27
            $cause = $e->getCause();
118 27
            if (mb_strpos($cause, 'java.io.FileNotFoundException') !== false) {
119
                if (file_exists($reportFile)) {
120
                    $exception = new Exception\ReportFileNotFoundFromJavaException(sprintf(
121 27
                        'Report file "%s" exists but cannot be located from the java side.',
122
                        $reportFile
123
                    ));
124
                } else {
125
                    $exception = new Exception\ReportFileNotFoundException(sprintf(
126
                        'Report file "%s" cannot be found',
127
                        $reportFile
128
                    ));
129
                }
130
            } elseif (mb_strpos($cause, 'org.xml.sax.SAXParseException') !== false) {
131
                $exception = new Exception\BrokenXMLReportFileException($e, sprintf(
132
                    'The report file "%s" cannot be parsed or not in jasper format',
133
                    $reportFile
134
                ));
135
            } elseif (mb_strpos($cause, 'Errors were encountered when compiling report expressions class file') !== false) {
136
                $exception = new Exception\ReportCompileException($e, sprintf(
137
                    'Report compilation failed for "%s"',
138
                    $reportFile
139
                ));
140
            } elseif (mb_strpos($cause, 'Error saving file:') !== false) {
141
                $exception = new Exception\JavaIOPermissionException($e, sprintf(
142
                    'Cannot save file, %s',
143
                    $cause
144
                ));
145
            }
146
        }
147
148
        return $exception ?? new Exception\JavaProxiedException(
149
                $e,
150
                sprintf(
151
                    'Error compiling report "%s"',
152
                    $reportFile
153
                )
154
            );
155
    }
156
157
    /**
158
     * @return JavaObject Java('net.sf.jasperreports.engine.JasperCompileManager')
159
     */
160
    public function getJavaProxiedObject(): JavaObject
161
    {
162
        if ($this->compileManager === null) {
163
            $this->compileManager = $this->ba->javaClass('net.sf.jasperreports.engine.JasperCompileManager');
164
        }
165
166
        return $this->compileManager;
167
    }
168
}
169