1 21 22 package com.jaspersoft.jasperserver.api.metadata.common.service.impl.hibernate; 23 24 import java.sql.SQLException ; 25 import java.util.ArrayList ; 26 import java.util.HashSet ; 27 import java.util.Iterator ; 28 import java.util.List ; 29 import java.util.Set ; 30 31 import org.apache.commons.logging.Log; 32 import org.apache.commons.logging.LogFactory; 33 import org.hibernate.HibernateException; 34 import org.hibernate.Session; 35 import org.hibernate.criterion.Conjunction; 36 import org.hibernate.criterion.DetachedCriteria; 37 import org.hibernate.criterion.Order; 38 import org.hibernate.criterion.Projections; 39 import org.hibernate.criterion.Restrictions; 40 import org.springframework.orm.hibernate3.HibernateCallback; 41 import org.springframework.orm.hibernate3.HibernateTemplate; 42 43 import com.jaspersoft.jasperserver.api.JSException; 44 import com.jaspersoft.jasperserver.api.JSExceptionWrapper; 45 import com.jaspersoft.jasperserver.api.common.domain.ExecutionContext; 46 import com.jaspersoft.jasperserver.api.metadata.common.domain.FileResourceData; 47 import com.jaspersoft.jasperserver.api.metadata.common.domain.Folder; 48 import com.jaspersoft.jasperserver.api.metadata.common.domain.Resource; 49 import com.jaspersoft.jasperserver.api.metadata.common.domain.ResourceLookup; 50 import com.jaspersoft.jasperserver.api.metadata.common.domain.ResourceReference; 51 import com.jaspersoft.jasperserver.api.metadata.common.service.JSResourceNotFoundException; 52 import com.jaspersoft.jasperserver.api.metadata.common.service.ResourceFactory; 53 import com.jaspersoft.jasperserver.api.metadata.common.service.impl.HibernateDaoImpl; 54 import com.jaspersoft.jasperserver.api.metadata.common.service.impl.hibernate.persistent.RepoFileResource; 55 import com.jaspersoft.jasperserver.api.metadata.common.service.impl.hibernate.persistent.RepoFolder; 56 import com.jaspersoft.jasperserver.api.metadata.common.service.impl.hibernate.persistent.RepoResource; 57 import com.jaspersoft.jasperserver.api.metadata.common.service.impl.hibernate.persistent.ContentRepoFileResource; 58 import com.jaspersoft.jasperserver.api.metadata.view.domain.FilterCriteria; 59 import com.jaspersoft.jasperserver.api.metadata.view.domain.FilterElement; 60 61 65 public class HibernateRepositoryServiceImpl extends HibernateDaoImpl implements HibernateRepositoryService, ReferenceResolver { 66 67 private static final Log log = LogFactory.getLog(HibernateRepositoryServiceImpl.class); 68 69 protected static final String TEMP_NAME_PREFIX = "*"; 70 protected static final int TEMP_NAME_PREFIX_LENGTH = TEMP_NAME_PREFIX.length(); 71 protected static final String CHILDREN_FOLDER_SUFFIX = "_files"; 72 73 private ResourceFactory resourceFactory; 74 private ResourceFactory persistentClassMappings; 75 private ThreadLocal tempNameResources; 76 77 public HibernateRepositoryServiceImpl() { 78 tempNameResources = new ThreadLocal (); 79 } 80 81 public ResourceFactory getPersistentClassMappings() { 82 return persistentClassMappings; 83 } 84 85 public void setPersistentClassMappings(ResourceFactory persistentClassMappings) { 86 this.persistentClassMappings = persistentClassMappings; 87 } 88 89 public ResourceFactory getResourceFactory() { 90 return resourceFactory; 91 } 92 93 public void setResourceFactory(ResourceFactory resourceFactory) { 94 this.resourceFactory = resourceFactory; 95 } 96 97 public Resource getResource(ExecutionContext context, final String uri) { 98 return (Resource) executeCallback(new DaoCallback() { 99 public Object execute() { 100 return loadResource(uri); 101 } 102 }); 103 } 104 105 protected Object loadResource(final String uri) { 106 RepoResource repoResource = findByURI(RepoResource.class, uri, false); 107 Resource resource; 108 if (repoResource == null) { 109 log.debug("Resource not found at \"" + uri + "\""); 110 resource = null; 111 } else { 112 resource = (Resource) repoResource.toClient(resourceFactory); 113 } 114 115 return resource; 116 } 117 118 public void saveFolder(ExecutionContext context, final Folder folder) { 119 executeWriteCallback(new DaoCallback() { 120 public Object execute() { 121 saveFolder(folder); 122 return null; 123 } 124 }); 125 } 126 127 protected void saveFolder(Folder folder) { 128 RepoFolder repoFolder = getFolder(folder.getURIString(), false); 129 130 if (folder.isNew()) { 131 if (repoFolder != null) { 132 throw new JSException("Folder \"" + folder.getURIString() + "\" already exists."); 133 } 134 135 repoFolder = new RepoFolder(); 136 repoFolder.setCreationDate(getOperationTimestamp()); 137 } else { 138 if (repoFolder == null) { 139 throw new JSException("Folder \"" + folder.getURIString() + "\" not found."); 140 } 141 } 142 143 String parentURI = folder.getParentFolder(); 144 RepoFolder parent = getFolder(parentURI, true); 145 repoFolder.set(folder, parent); 147 getHibernateTemplate().saveOrUpdate(repoFolder); 148 } 149 150 151 protected RepoFolder getFolder(String uri, boolean required) { 152 if (uri == null || uri.length() == 0 || uri.equals(Folder.SEPARATOR)) { 153 return getRootFolder(); 154 } 155 156 158 final String repoURIPrefix = Resource.URI_PROTOCOL + ":"; 159 String workUri = uri.startsWith(repoURIPrefix) ? uri.substring(repoURIPrefix.length()) : uri; 160 161 DetachedCriteria criteria = DetachedCriteria.forClass(RepoFolder.class); 162 criteria.add(Restrictions.naturalId().set("URI", workUri)); 163 List foldersList = getHibernateTemplate().findByCriteria(criteria); 164 RepoFolder folder; 165 if (foldersList.isEmpty()) { 166 if (required) { 167 throw new JSResourceNotFoundException("Folder not found at \"" + uri + "\""); 168 } 169 170 log.debug("Folder not found at \"" + uri + "\""); 171 folder = null; 172 } else { 173 folder = (RepoFolder) foldersList.get(0); 174 } 175 return folder; 176 } 177 178 protected RepoFolder getRootFolder() { 179 DetachedCriteria criteria = DetachedCriteria.forClass(RepoFolder.class); 180 criteria.add(Restrictions.naturalId().set("URI", Folder.SEPARATOR)); 181 List foldersList = getHibernateTemplate().findByCriteria(criteria); 182 RepoFolder root; 183 if (foldersList.isEmpty()) { 184 root = new RepoFolder(); 186 root.setCreationDate(getOperationTimestamp()); 187 root.setName(Folder.SEPARATOR); 188 root.setLabel("root"); 189 root.setDescription("Root of the folder hierarchy"); 190 root.setURI(Folder.SEPARATOR); 191 root.setHidden(false); 192 root.setParent(null); 193 getHibernateTemplate().saveOrUpdate(root); 194 } else { 195 root = (RepoFolder) foldersList.get(0); 196 } 197 return root; 198 } 199 200 public void saveResource(ExecutionContext context, final Resource resource) { 201 initTempNameResources(); 202 try { 203 executeWriteCallback(new DaoCallback() { 204 public Object execute() { 205 RepoResource repo = getRepoResource(resource); 206 repo.copyFromClient(resource, HibernateRepositoryServiceImpl.this); 207 RepoResource repositoryResource = repo; 208 getHibernateTemplate().saveOrUpdate(repositoryResource); 209 return null; 210 } 211 }); 212 213 if (!tempNameResources().isEmpty()) { 214 executeWriteCallback(new DaoCallback() { 215 public Object execute() { 216 HibernateTemplate template = getHibernateTemplate(); 217 for (Iterator it = tempNameResources().iterator(); it.hasNext();) { 218 RepoResource res = (RepoResource) it.next(); 219 res.setName(res.getName().substring(TEMP_NAME_PREFIX_LENGTH)); 220 template.save(res); 221 } 222 return null; 223 } 224 }); 225 } 226 } finally { 227 resetTempNameResources(); 228 } 229 } 230 231 protected void initTempNameResources() { 232 tempNameResources.set(new HashSet ()); 233 } 234 235 protected void resetTempNameResources() { 236 tempNameResources.set(null); 237 } 238 239 protected Set tempNameResources() { 240 return (Set ) tempNameResources.get(); 241 } 242 243 public RepoResource getRepoResource(Resource resource) { 244 Class persistentClass = getPersistentClassMappings().getImplementationClass(resource.getClass()); 245 if (persistentClass == null) { 246 throw new JSException("No persistent class is mapped to \"" + resource.getClass().getName() + "\"."); 247 } 248 249 RepoResource repo; 250 if (resource.isNew()) { 251 if (resourceExists(resource.getURIString())) { 252 throw new JSException("Resource \"" + resource.getURIString() + "\" already exists."); 253 } 254 255 repo = createPersistentResource(persistentClass); 256 257 RepoFolder parent = getFolder(resource.getParentFolder(), true); 258 repo.setParent(parent); 259 } else { 260 repo = findByURI(persistentClass, resource.getURIString(), false); 261 if (repo == null) { 262 throw new JSException("Resource \"" + resource.getURIString() + "\" does not exist."); 263 } 264 } 265 return repo; 266 } 267 268 protected boolean resourceExists(String uri) { 269 int sep = uri.lastIndexOf(Folder.SEPARATOR); 270 boolean exists = false; 271 if (sep >= 0) { 272 String name = uri.substring(sep + Folder.SEPARATOR_LENGTH); 273 String folderName = uri.substring(0, sep); 274 RepoFolder folder = getFolder(folderName, false); 275 if (folder != null) { 276 exists = resourceExists(folder, name); 277 } 278 } 279 return exists; 280 } 281 282 public ResourceLookup[] findResource(ExecutionContext context, final FilterCriteria filterCriteria) 283 { 284 return (ResourceLookup[]) executeCallback(new DaoCallback() { 285 public Object execute() { 286 return loadResources(filterCriteria); 287 } 288 }); 289 } 290 291 public List loadClientResources(FilterCriteria filterCriteria) { 292 293 List repoResources = loadRepoResourceList(filterCriteria); 294 295 List result = new ArrayList (repoResources.size()); 296 297 for (Iterator iter = repoResources.iterator(); iter.hasNext(); ) { 298 RepoResource repoResource = (RepoResource) iter.next(); 299 result.add(repoResource.toClient(resourceFactory)); 300 } 301 return result; 302 } 303 304 public List loadResourcesList(FilterCriteria filterCriteria) { 305 306 List repoResources = loadRepoResourceList(filterCriteria); 307 308 List result = new ArrayList (repoResources.size()); 309 310 for (Iterator iter = repoResources.iterator(); iter.hasNext(); ) { 311 RepoResource repoResource = (RepoResource) iter.next(); 312 result.add(repoResource.toClientLookup()); 313 } 314 return result; 315 } 316 317 protected Object loadResources(FilterCriteria filterCriteria) { 318 319 List repoResources = loadResourcesList(filterCriteria); 320 321 ResourceLookup[] resourceLookups = new ResourceLookup[repoResources.size()]; 322 int i = 0; 323 for (Iterator iter = repoResources.iterator(); iter.hasNext(); ++i) { 324 resourceLookups[i] = (ResourceLookup) iter.next(); 325 } 326 return resourceLookups; 327 } 328 329 public List loadRepoResourceList(final FilterCriteria filterCriteria) { 330 Class filterClass = filterCriteria == null ? null : filterCriteria.getFilterClass(); 331 Class persistentClass; 332 if (filterClass == null) { 333 persistentClass = RepoResource.class; 334 } else { 335 persistentClass = getPersistentClassMappings().getImplementationClass(filterClass); 336 } 337 338 340 if (persistentClass == null) { 341 return new ArrayList (); 342 } 343 344 DetachedCriteria criteria = DetachedCriteria.forClass(persistentClass); 345 criteria.createAlias("parent", "parent"); 346 criteria.add(Restrictions.eq("parent.hidden", Boolean.FALSE)); 347 348 if (filterCriteria != null) { 349 List filterElements = filterCriteria.getFilterElements(); 350 if (!filterElements.isEmpty()) { 351 Conjunction conjunction = Restrictions.conjunction(); 352 HibernateFilter filter = new HibernateFilter(conjunction); 353 for (Iterator it = filterElements.iterator(); it.hasNext();) { 354 FilterElement filterElement = (FilterElement) it.next(); 355 filterElement.apply(filter); 356 } 357 criteria.add(conjunction); 358 } 359 } 360 361 criteria.addOrder(Order.asc("parent.URI")); 362 criteria.addOrder(Order.asc("name")); 363 364 return getHibernateTemplate().findByCriteria(criteria); 365 366 } 367 368 public Resource newResource(ExecutionContext context, Class _class) { 369 return resourceFactory.newResource(context, _class); 370 } 371 372 public RepoResource findByURI(Class persistentClass, String uri, boolean required) { 373 if (uri == null) { 374 throw new JSException("Null URI"); 375 } 376 377 379 final String repoURIPrefix = Resource.URI_PROTOCOL + ":"; 380 String workUri = uri.startsWith(repoURIPrefix) ? uri.substring(repoURIPrefix.length()) : uri; 381 382 int sep = workUri.lastIndexOf(Folder.SEPARATOR); 383 RepoResource res = null; 384 if (sep >= 0) { 385 String name = workUri.substring(sep + Folder.SEPARATOR_LENGTH); 386 String folderName = workUri.substring(0, sep); 387 log.debug("Looking for name: " + name + " in folder: " + folderName); 388 RepoFolder folder = getFolder(folderName, false); 389 if (folder != null) { 390 res = findByName(persistentClass, folder, name, required); 391 } else { 392 log.warn("No folder: " + folderName); 393 } 394 } 395 396 if (required && res == null) { 397 throw new JSResourceNotFoundException("Resource \"" + uri + "\" of type " + persistentClass + " not found."); 398 } 399 400 return res; 401 } 402 403 protected RepoResource findByName(Class persistentClass, RepoFolder folder, String name, boolean required) { 404 DetachedCriteria criteria = DetachedCriteria.forClass(persistentClass); 405 criteria.add(Restrictions.naturalId().set("name", name).set("parent", folder)); 406 List resourceList = getHibernateTemplate().findByCriteria(criteria); 407 408 RepoResource res; 409 if (resourceList.isEmpty()) { 410 if (required) { 411 String uri = folder.getURI() + Folder.SEPARATOR + name; 412 throw new JSResourceNotFoundException("Resource \"" + uri + "\" of type " + persistentClass + " not found."); 413 } 414 415 res = null; 416 } 417 else { 418 res = (RepoResource) resourceList.get(0); 419 } 420 421 return res; 422 } 423 424 protected boolean resourceExists(RepoFolder folder, String name) { 425 DetachedCriteria criteria = DetachedCriteria.forClass(RepoResource.class); 426 criteria.add(Restrictions.naturalId().set("name", name).set("parent", folder)); 427 criteria.setProjection(Projections.rowCount()); 428 List countList = getHibernateTemplate().findByCriteria(criteria); 429 int count = ((Integer ) countList.get(0)).intValue(); 430 return count > 0; 431 } 432 433 protected RepoResource createPersistentResource(Class persistentClass) { 434 try { 435 RepoResource repo = (RepoResource) persistentClass.newInstance(); 436 repo.setCreationDate(getOperationTimestamp()); 437 return repo; 438 } catch (InstantiationException e) { 439 log.fatal("Error instantiating persistent resource", e); 440 throw new JSExceptionWrapper(e); 441 } catch (IllegalAccessException e) { 442 log.fatal("Error instantiating persistent resource", e); 443 throw new JSExceptionWrapper(e); 444 } 445 } 446 447 protected RepoResource getRepositoryReference(RepoResource owner, Resource res) { 448 Class persistentClass = getPersistentClassMappings().getImplementationClass(res.getClass()); 449 if (persistentClass == null) { 450 throw new JSException("No persistent class is mapped to \"" + res.getClass().getName() + "\"."); 451 } 452 453 RepoResource repo = null; 454 RepoFolder folder = owner.getChildrenFolder(); 455 if (res.isNew()) { 456 boolean tempName = folder != null && !folder.isNew() && resourceExists(folder, res.getName()); 458 repo = createPersistentResource(persistentClass); 459 if (tempName) { 460 tempNameResources().add(repo); 461 } 462 } else { 463 if (folder != null && !folder.isNew()) { 464 repo = findByName(persistentClass, folder, res.getName(), false); 465 } 466 if (repo == null) { 467 throw new JSException("Resource \"" + res.getURIString() + "\" does not exist."); 468 } 469 } 470 471 return repo; 472 } 473 474 477 public RepoResource getReference(RepoResource owner, ResourceReference resourceRef, Class persistentReferenceClass) { 478 if (resourceRef == null) { 479 return null; 480 } 481 RepoResource repoRes; 482 if (resourceRef.isLocal()) { 483 repoRes = getReference(owner, resourceRef.getLocalResource(), persistentReferenceClass); 484 } else { 485 repoRes = findByURI(persistentReferenceClass, resourceRef.getReferenceURI(), true); 486 } 487 return repoRes; 488 } 489 490 public RepoResource getReference(RepoResource owner, Resource resource, Class persistentReferenceClass) { 491 if (resource == null) { 492 return null; 493 } 494 495 RepoResource repoRes = getRepositoryReference(owner, resource); 496 497 RepoFolder local = owner.getChildrenFolder(); 498 if (local == null) { 499 if (log.isInfoEnabled()) { 500 log.info("Creating children folder for " + this); 501 } 502 503 local = new RepoFolder(); 504 local.setCreationDate(getOperationTimestamp()); 505 local.setName(getChildrenFolderName(owner.getName())); 506 local.setLabel(owner.getLabel()); 507 local.setDescription(owner.getDescription()); 508 local.setParent(owner.getParent()); 509 local.setHidden(true); 510 local.setURI(); 511 owner.setChildrenFolder(local); 512 } 513 514 owner.addNewChild(repoRes); 515 repoRes.copyFromClient(resource, this); 516 517 if (tempNameResources().contains(repoRes)) { 518 repoRes.setName(TEMP_NAME_PREFIX + repoRes.getName()); 519 } 520 521 return repoRes; 522 } 523 524 public List getAllFolders(ExecutionContext context) { 525 return (List ) executeCallback(new DaoCallback() { 526 public Object execute() { 527 DetachedCriteria criteria = DetachedCriteria.forClass(RepoFolder.class); 528 criteria.add(Restrictions.eq("hidden", Boolean.FALSE)); 529 criteria.addOrder(Order.asc("URI")); 530 531 List repoFolders = getHibernateTemplate().findByCriteria(criteria); 532 List folders = new ArrayList (repoFolders.size()); 533 for (Iterator iter = repoFolders.iterator(); iter.hasNext();) { 534 RepoFolder repoFolder = (RepoFolder) iter.next(); 535 Folder folder = repoFolder.toClient(); 536 folders.add(folder); 537 } 538 return folders; 539 } 540 }); 541 } 542 543 public List getSubFolders(ExecutionContext context, final String folderURI) { 544 return (List ) executeCallback(new DaoCallback() { 545 public Object execute() { 546 final RepoFolder folder = getFolder(folderURI, false); 547 List subfolders; 548 if (folder == null) { 549 subfolders = new ArrayList (); 551 } else { 552 List folders = getHibernateTemplate().executeFind(new HibernateCallback() { 553 public Object doInHibernate(Session session) throws HibernateException, SQLException { 554 return session.createFilter(folder.getSubFolders(), "where hidden = false order by name").list(); 555 } 556 }); 557 558 subfolders = new ArrayList (folders.size()); 559 for (Iterator it = folders.iterator(); it.hasNext();) { 560 RepoFolder repoFolder = (RepoFolder) it.next(); 561 subfolders.add(repoFolder.toClient()); 562 } 563 } 564 return subfolders; 565 } 566 }); 567 } 568 569 public FileResourceData getResourceData(ExecutionContext context, final String uri) throws JSResourceNotFoundException { 570 return (FileResourceData) executeCallback(new DaoCallback() { 571 public Object execute() { 572 RepoFileResource res = (RepoFileResource) findByURI(RepoFileResource.class, uri, true); 573 while (res.isFileReference()) { 574 res = res.getReference(); 575 } 576 return res.copyData(); 577 } 578 }); 579 } 580 581 public FileResourceData getContentResourceData(ExecutionContext context, final String uri) throws JSResourceNotFoundException { 582 return (FileResourceData) executeCallback(new DaoCallback() { 583 public Object execute() { 584 ContentRepoFileResource res = (ContentRepoFileResource) findByURI(ContentRepoFileResource.class, uri, true); 585 return res.copyData(); 586 } 587 }); 588 } 589 590 public RepoResource getExternalReference(String uri, Class persistentReferenceClass) { 591 return findByURI(persistentReferenceClass, uri, true); 592 } 593 594 public void deleteResource(ExecutionContext context, final String uri) { 595 executeWriteCallback(new DaoCallback() { 596 public Object execute() { 597 deleteResource(uri); 598 return null; 599 } 600 }); 601 } 602 603 protected void deleteResource(String uri) { 604 RepoResource repoResource = findByURI(RepoResource.class, uri, true); 605 getHibernateTemplate().delete(repoResource); 606 } 607 608 public void deleteFolder(ExecutionContext context, final String uri) { 609 executeWriteCallback(new DaoCallback() { 610 public Object execute() { 611 deleteFolder(uri); 612 return null; 613 } 614 }); 615 } 616 617 protected void deleteFolder(String uri) { 618 RepoFolder folder = getFolder(uri, true); 619 getHibernateTemplate().delete(folder); 620 } 621 622 public void delete(ExecutionContext context, final String [] resourceURIs, final String [] folderURIs) { 623 executeWriteCallback(new DaoCallback() { 624 public Object execute() { 625 if (resourceURIs != null && resourceURIs.length > 0) { 626 for (int i = 0; i < resourceURIs.length; i++) { 627 deleteResource(resourceURIs[i]); 628 } 629 } 630 631 if (folderURIs != null && folderURIs.length > 0) { 632 for (int i = 0; i < folderURIs.length; i++) { 633 deleteFolder(folderURIs[i]); 634 } 635 } 636 637 return null; 638 } 639 }); 640 } 641 642 public Folder getFolder(ExecutionContext context, final String uri) { 643 return (Folder) executeCallback(new DaoCallback() { 644 public Object execute() { 645 RepoFolder repoFolder = getFolder(uri, false); 646 Folder folder = repoFolder == null ? null : repoFolder.toClient(); 647 return folder; 648 } 649 }); 650 } 651 652 653 public String getChildrenFolderName(String resourceName) 654 { 655 return resourceName + CHILDREN_FOLDER_SUFFIX; 656 } 657 } 658 | Popular Tags |