Advertisement
Guest User

Untitled

a guest
Mar 28th, 2017
42
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 12.44 KB | None | 0 0
  1. package org.realityforge.sqlserver.ssrs;
  2.  
  3. import java.io.DataInputStream;
  4. import java.io.File;
  5. import java.io.FileInputStream;
  6. import java.io.FileOutputStream;
  7. import java.io.IOException;
  8. import java.net.URL;
  9. import java.util.ArrayList;
  10. import java.util.List;
  11. import java.util.logging.ConsoleHandler;
  12. import java.util.logging.Formatter;
  13. import java.util.logging.Level;
  14. import java.util.logging.LogRecord;
  15. import java.util.logging.Logger;
  16. import javax.xml.namespace.QName;
  17. import org.realityforge.sqlserver.ssrs.reportingservice2005.ArrayOfCatalogItem;
  18. import org.realityforge.sqlserver.ssrs.reportingservice2005.ArrayOfProperty;
  19. import org.realityforge.sqlserver.ssrs.reportingservice2005.ArrayOfWarning;
  20. import org.realityforge.sqlserver.ssrs.reportingservice2005.CatalogItem;
  21. import org.realityforge.sqlserver.ssrs.reportingservice2005.CredentialRetrievalEnum;
  22. import org.realityforge.sqlserver.ssrs.reportingservice2005.DataSourceDefinition;
  23. import org.realityforge.sqlserver.ssrs.reportingservice2005.ItemTypeEnum;
  24. import org.realityforge.sqlserver.ssrs.reportingservice2005.ReportingService2005;
  25. import org.realityforge.sqlserver.ssrs.reportingservice2005.ReportingService2005Soap;
  26. import org.realityforge.sqlserver.ssrs.reportingservice2005.Warning;
  27.  
  28. /**
  29. * Adapter class for interacting with the SSRS service from ruby code.
  30. */
  31. @SuppressWarnings( { "UnusedDeclaration" } )
  32. public class SSRS
  33. {
  34. private static final Logger LOG = Logger.getLogger( SSRS.class.getName() );
  35. private static final String PATH_SEPARATOR = "/";
  36.  
  37. private final ReportingService2005Soap _soap;
  38. private final String _prefix;
  39.  
  40. /**
  41. * Create an adapter for a specific service, acting on a particular path.
  42. *
  43. * @param wsdlURL the URL to the wsdl for the service
  44. * @param prefix the prefix for all reports interacted with by this adapter
  45. */
  46. public SSRS( final URL wsdlURL, final String prefix )
  47. {
  48. if ( null == wsdlURL )
  49. {
  50. throw new NullPointerException( "wsdlURL" );
  51. }
  52. if ( null == prefix )
  53. {
  54. throw new NullPointerException( "prefix" );
  55. }
  56. _prefix = prefix;
  57. final QName qName =
  58. new QName( "http://schemas.microsoft.com/sqlserver/2005/06/30/reporting/reportingservices",
  59. "ReportingService2005" );
  60. final ReportingService2005 service = new ReportingService2005( wsdlURL, qName );
  61. _soap = service.getReportingService2005Soap();
  62. }
  63.  
  64. /**
  65. * A helper method to configure the logging.
  66. * Used from jruby.
  67. */
  68. public static void setupLogger( final boolean verbose )
  69. {
  70. LOG.setUseParentHandlers( false );
  71. LOG.setLevel( verbose ? Level.ALL : Level.INFO );
  72. final ConsoleHandler handler = new ConsoleHandler();
  73. handler.setFormatter( new Formatter()
  74. {
  75. @Override
  76. public String format( final LogRecord record )
  77. {
  78. return record.getMessage() + "\n";
  79. }
  80. } );
  81. LOG.addHandler( handler );
  82. }
  83.  
  84. /**
  85. * Log a info message.
  86. * Used from ruby code. (Not using LOG directly as overloading confuses ruby)
  87. */
  88. public static void info( final String message )
  89. {
  90. LOG.info( message );
  91. }
  92.  
  93. /**
  94. * Log a warning message.
  95. * Used from ruby code. (Not using LOG directly as overloading confuses ruby)
  96. */
  97. public static void warning( final String message )
  98. {
  99. LOG.warning( message );
  100. }
  101.  
  102. /**
  103. * Create a data source at path with a specific connection string.
  104. */
  105. public void createSQLDataSource( final String path, final String connectionString )
  106. {
  107. final DataSourceDefinition definition = new DataSourceDefinition();
  108. definition.setConnectString( connectionString );
  109. definition.setEnabled( true );
  110. definition.setExtension( "SQL" );
  111. definition.setImpersonateUser( false );
  112. definition.setPrompt( null );
  113. definition.setCredentialRetrieval( CredentialRetrievalEnum.NONE );
  114. definition.setWindowsCredentials( false );
  115. createDataSource( path, definition );
  116. }
  117.  
  118. /**
  119. * Create a data source at path with a using a complete data definition.
  120. */
  121. public void createDataSource( final String path, final DataSourceDefinition definition )
  122. {
  123. info( "Creating DataSource " + path );
  124. final String physicalName = toPhysicalFileName( path );
  125. final String reportName = filenameFromPath( physicalName );
  126. final String reportDir = dirname( physicalName );
  127.  
  128. final ItemTypeEnum type = _soap.getItemType( physicalName );
  129. if ( ItemTypeEnum.UNKNOWN != type )
  130. {
  131. final String s = "Can not create data source as path " + path + " exists and is of type " + type + ".";
  132. throw new IllegalStateException( s );
  133. }
  134. else
  135. {
  136. _soap.createDataSource( reportName, reportDir, false, definition, new ArrayOfProperty() );
  137. }
  138. }
  139.  
  140. /**
  141. * Create a report at specific path from specified report file. Path must not exist.
  142. */
  143. public void createReport( final String path, final String filename )
  144. {
  145. final File file = new File( filename );
  146. info( "Creating Report " + path );
  147. final String physicalName = toPhysicalFileName( path );
  148. LOG.fine( "Creating Report with symbolic item " + path + " as " + physicalName );
  149. final ItemTypeEnum type = _soap.getItemType( physicalName );
  150. if ( ItemTypeEnum.UNKNOWN != type )
  151. {
  152. final String s = "Can not create report as path " + physicalName + " exists and is of type " + type + ".";
  153. throw new IllegalStateException( s );
  154. }
  155. else
  156. {
  157. final byte[] bytes = readFully( path, file );
  158. final String reportName = filenameFromPath( physicalName );
  159. final String reportDir = dirname( physicalName );
  160. LOG.finer( "Invoking createReport(name=" + reportName + ",parentDir=" + reportDir + ")" );
  161. final ArrayOfWarning warnings =
  162. _soap.createReport( reportName, reportDir, true, bytes, new ArrayOfProperty() );
  163.  
  164. if ( null != warnings )
  165. {
  166. final String message =
  167. "createReport(name=" + reportName + ",parentDir=" + reportDir + ") from " + file.getAbsolutePath();
  168. logWarnings( message, warnings );
  169. }
  170. }
  171. }
  172.  
  173. /**
  174. * Create a report at specific path from specified report file. Path must not exist.
  175. */
  176. public void downloadReport( final String path, final String filename )
  177. {
  178. final File file = new File( filename );
  179. final String physicalName = toPhysicalFileName( path );
  180.  
  181. info( "Downloading Report with symbolic name " + path + " to " + file );
  182.  
  183. final byte[] data = _soap.getReportDefinition( physicalName );
  184.  
  185. try ( final FileOutputStream out = new FileOutputStream( file ) )
  186. {
  187. out.write( data );
  188. }
  189. catch ( final IOException ioe )
  190. {
  191. final String message = "Failed to download report with symbolic name " + path + " to " + file;
  192. LOG.warning( message );
  193. if ( file.exists() && !file.delete() )
  194. {
  195. throw new IllegalStateException( message + " and failed to delete temporary file", ioe );
  196. }
  197. else
  198. {
  199. throw new IllegalStateException( message, ioe );
  200.  
  201. }
  202. }
  203. }
  204.  
  205. /**
  206. * List files at symbolic path.
  207. */
  208. public String[] listReports( final String path )
  209. {
  210. info( "Listing Reports at " + path );
  211. final List<CatalogItem> catalogItems = listItems( path );
  212. final ArrayList<String> list = new ArrayList<String>();
  213. for ( final CatalogItem item : catalogItems )
  214. {
  215. if ( item.getType() == ItemTypeEnum.REPORT )
  216. {
  217. list.add( item.getName() );
  218. }
  219. }
  220. return list.toArray( new String[ list.size() ] );
  221. }
  222.  
  223. /**
  224. * List directories at symbolic path.
  225. */
  226. public String[] listFolders( final String path )
  227. {
  228. info( "Listing Folders at " + path );
  229. final List<CatalogItem> catalogItems = listItems( path );
  230.  
  231. final ArrayList<String> list = new ArrayList<String>();
  232. for ( final CatalogItem item : catalogItems )
  233. {
  234. if ( item.getType() == ItemTypeEnum.FOLDER )
  235. {
  236. list.add( item.getName() );
  237. }
  238. }
  239. return list.toArray( new String[ list.size() ] );
  240. }
  241.  
  242. /**
  243. * Delete symbolic path and all sub elements. Will skip if no such path.
  244. */
  245. public void delete( final String path )
  246. {
  247. info( "Deleting item " + path );
  248. final String physicalName = toPhysicalFileName( path );
  249. LOG.fine( "Deleting symbolic item " + path + " as " + physicalName );
  250. final ItemTypeEnum type = _soap.getItemType( physicalName );
  251. if ( ItemTypeEnum.UNKNOWN == type )
  252. {
  253. LOG.finer( "Skipping invocation of deleteItem(item=" + physicalName + ") as item does not exist." );
  254. }
  255. else
  256. {
  257. LOG.finer( "Invoking deleteItem(item=" + physicalName + ")" );
  258. _soap.deleteItem( physicalName );
  259. }
  260. }
  261.  
  262. /**
  263. * Create a directory node at specified path. Path must not exist.
  264. */
  265. public void mkdir( final String filePath )
  266. {
  267. info( "Creating dir " + filePath );
  268. final String physicalName = toPhysicalFileName( filePath );
  269. LOG.fine( "Creating symbolic dir " + filePath + " as " + physicalName );
  270. final StringBuilder path = new StringBuilder();
  271. for ( final String dir : physicalName.substring( 1 ).split( PATH_SEPARATOR ) )
  272. {
  273. final String parentDir = ( path.length() == 0 ) ? PATH_SEPARATOR : path.toString();
  274. final ItemTypeEnum type = _soap.getItemType( path.toString() + PATH_SEPARATOR + dir );
  275. if ( ItemTypeEnum.UNKNOWN == type )
  276. {
  277. LOG.finer( "Invoking createFolder(dir=" + dir + ",parentDir=" + parentDir + ")" );
  278. _soap.createFolder( dir, parentDir, new ArrayOfProperty() );
  279. }
  280. else if ( ItemTypeEnum.FOLDER != type )
  281. {
  282. final String s = "Path " + path + " exists and is not a folder but a " + type;
  283. throw new IllegalStateException( s );
  284. }
  285. else
  286. {
  287. final String message =
  288. "Skipping invocation of createFolder(dir=" + dir + ",parentDir=" + parentDir + ") as folder exists";
  289. LOG.finer( message );
  290. }
  291. path.append( PATH_SEPARATOR );
  292. path.append( dir );
  293. }
  294. }
  295.  
  296. private String filenameFromPath( final String path )
  297. {
  298. final int index = path.lastIndexOf( PATH_SEPARATOR );
  299. if ( -1 == index )
  300. {
  301. return path;
  302. }
  303. else
  304. {
  305. return path.substring( index + 1 );
  306. }
  307. }
  308.  
  309. private String dirname( final String path )
  310. {
  311. final int index = path.lastIndexOf( PATH_SEPARATOR );
  312. if ( -1 == index )
  313. {
  314. return "";
  315. }
  316. else
  317. {
  318. return path.substring( 0, index );
  319. }
  320. }
  321.  
  322. /**
  323. * Return the fully qualified path for specified name.
  324. */
  325. private String toPhysicalFileName( final String name )
  326. {
  327. return nameComponent( _prefix ) + nameComponent( name );
  328. }
  329.  
  330. private String nameComponent( final String name )
  331. {
  332. if ( 0 == name.length() || PATH_SEPARATOR.equals( name ) )
  333. {
  334. return "";
  335. }
  336. else if ( name.startsWith( PATH_SEPARATOR ) )
  337. {
  338. return name;
  339. }
  340. else
  341. {
  342. return PATH_SEPARATOR + name;
  343. }
  344. }
  345.  
  346. private void logWarnings( final String message, final ArrayOfWarning warnings )
  347. {
  348. for ( final Warning warning : warnings.getWarning() )
  349. {
  350. warning( "Action '" + message + "' resulted in warning " +
  351. " Code=" + warning.getCode() +
  352. " ObjectName=" + warning.getObjectName() +
  353. " ObjectType=" + warning.getObjectType() +
  354. " Severity=" + warning.getSeverity() +
  355. " Message=" + warning.getMessage() );
  356. }
  357. }
  358.  
  359. private byte[] readFully( final String name, final File file )
  360. {
  361. if ( !file.exists() )
  362. {
  363. final String message = "Report file " + file.getAbsolutePath() + " for " + name + " does not exist.";
  364. throw new IllegalStateException( message );
  365. }
  366. try
  367. {
  368. final byte[] bytes = new byte[ (int) file.length() ];
  369. new DataInputStream( new FileInputStream( file ) ).readFully( bytes );
  370. return bytes;
  371. }
  372. catch ( IOException e )
  373. {
  374. throw new IllegalStateException( "Unable to load report file " + file.getAbsolutePath() );
  375. }
  376. }
  377.  
  378. private List<CatalogItem> listItems( final String path )
  379. {
  380. final String physicalName = toPhysicalFileName( path );
  381. LOG.finer( "Invoking listChildren(item=" + physicalName + ")" );
  382. final ArrayOfCatalogItem children = _soap.listChildren( physicalName, false );
  383. return children.getCatalogItem();
  384. }
  385. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement