Changeset 2556


Ignore:
Timestamp:
02/08/13 15:11:58 (11 years ago)
Author:
twagoo
Message:

Component usage checking:

  • REST method has userspace=true default (like other methods)
  • Faster failure on deletion of used component (at the expense of explanatory details in error response)
  • Added test for this

Refs #275

Location:
ComponentRegistry/trunk/ComponentRegistry/src
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • ComponentRegistry/trunk/ComponentRegistry/src/main/java/clarin/cmdi/componentregistry/impl/ComponentRegistryImplBase.java

    r1689 r2556  
    2424
    2525/**
    26  * 
     26 *
    2727 * @author Twan Goosen <twan.goosen@mpi.nl>
    2828 */
     
    3333    @Override
    3434    public List<ComponentDescription> getUsageInComponents(String componentId) throws ComponentRegistryException {
    35         List<ComponentDescription> result = new ArrayList<ComponentDescription>();
    36         List<ComponentDescription> descs = getComponentDescriptions();
    37         for (ComponentDescription desc : descs) {
    38             CMDComponentSpec spec = getMDComponent(desc.getId());
    39             if (spec != null && findComponentId(componentId, spec.getCMDComponent())) {
    40                 result.add(desc);
    41             }
    42         }
    43         return result;
     35        List<ComponentDescription> result = new ArrayList<ComponentDescription>();
     36        List<ComponentDescription> descs = getComponentDescriptions();
     37        for (ComponentDescription desc : descs) {
     38            CMDComponentSpec spec = getMDComponent(desc.getId());
     39            if (spec != null && findComponentId(componentId, spec.getCMDComponent())) {
     40                result.add(desc);
     41            }
     42        }
     43        return result;
    4444    }
    4545
    4646    @Override
    4747    public List<ProfileDescription> getUsageInProfiles(String componentId) throws ComponentRegistryException {
    48         List<ProfileDescription> result = new ArrayList<ProfileDescription>();
    49         for (ProfileDescription profileDescription : getProfileDescriptions()) {
    50             CMDComponentSpec profile = getMDProfile(profileDescription.getId());
    51             if (profile != null && findComponentId(componentId, profile.getCMDComponent())) {
    52                 result.add(profileDescription);
    53             }
    54         }
    55         return result;
     48        List<ProfileDescription> result = new ArrayList<ProfileDescription>();
     49        for (ProfileDescription profileDescription : getProfileDescriptions()) {
     50            CMDComponentSpec profile = getMDProfile(profileDescription.getId());
     51            if (profile != null && findComponentId(componentId, profile.getCMDComponent())) {
     52                result.add(profileDescription);
     53            }
     54        }
     55        return result;
    5656    }
    5757
    5858    /**
    59      * 
     59     *
    6060     * @return List of profile descriptions ordered by name ascending, only the ones marked for showing in metadata editor
    6161     * @throws ComponentRegistryException
     
    6363    @Override
    6464    public List<ProfileDescription> getProfileDescriptionsForMetadaEditor() throws ComponentRegistryException {
    65         // TODO: Below can also be done by accepting and passing a parameter in the ProfileDescriptionDao, should have better performance
     65        // TODO: Below can also be done by accepting and passing a parameter in the ProfileDescriptionDao, should have better performance
    6666
    67         // Get all profile descriptions
    68         List<ProfileDescription> descriptionsCollection = getProfileDescriptions();
    69         // Filter out ones that do should not be shown for metadata editor
    70         ArrayList<ProfileDescription> descriptions = new ArrayList<ProfileDescription>(descriptionsCollection.size());
    71         for (ProfileDescription profile : descriptionsCollection) {
    72             if (((ProfileDescription) profile).isShowInEditor()) {
    73                 descriptions.add((ProfileDescription) profile);
    74             }
    75         }
    76         // Return filtered list
    77         return descriptions;
     67        // Get all profile descriptions
     68        List<ProfileDescription> descriptionsCollection = getProfileDescriptions();
     69        // Filter out ones that do should not be shown for metadata editor
     70        ArrayList<ProfileDescription> descriptions = new ArrayList<ProfileDescription>(descriptionsCollection.size());
     71        for (ProfileDescription profile : descriptionsCollection) {
     72            if (((ProfileDescription) profile).isShowInEditor()) {
     73                descriptions.add((ProfileDescription) profile);
     74            }
     75        }
     76        // Return filtered list
     77        return descriptions;
    7878    }
    7979
    8080    /* HELPER METHODS */
    8181    protected static String stripRegistryId(String id) {
    82         return StringUtils.removeStart(id, ComponentRegistry.REGISTRY_ID);
     82        return StringUtils.removeStart(id, ComponentRegistry.REGISTRY_ID);
    8383    }
    8484
    8585    protected static void enrichSpecHeader(CMDComponentSpec spec, AbstractDescription description) {
    86         Header header = spec.getHeader();
    87         header.setID(description.getId());
    88         if (StringUtils.isEmpty(header.getName())) {
    89             header.setName(description.getName());
    90         }
    91         if (StringUtils.isEmpty(header.getDescription())) {
    92             header.setDescription(description.getDescription());
    93         }
     86        Header header = spec.getHeader();
     87        header.setID(description.getId());
     88        if (StringUtils.isEmpty(header.getName())) {
     89            header.setName(description.getName());
     90        }
     91        if (StringUtils.isEmpty(header.getDescription())) {
     92            header.setDescription(description.getDescription());
     93        }
    9494    }
    95        
     95
    9696    protected static boolean findComponentId(String componentId, List<CMDComponentType> componentReferences) {
    97         for (CMDComponentType cmdComponent : componentReferences) {
    98             if (componentId.equals(cmdComponent.getComponentId())) {
    99                 return true;
    100             } else if (findComponentId(componentId, cmdComponent.getCMDComponent())) {
    101                 return true;
    102             }
    103         }
    104         return false;
     97        for (CMDComponentType cmdComponent : componentReferences) {
     98            if (componentId.equals(cmdComponent.getComponentId())) {
     99                return true;
     100            } else if (findComponentId(componentId, cmdComponent.getCMDComponent())) {
     101                return true;
     102            }
     103        }
     104        return false;
    105105    }
    106106
    107107    protected static void writeXsd(CMDComponentSpec expandedSpec, OutputStream outputStream) {
    108         MDMarshaller.generateXsd(expandedSpec, outputStream);
     108        MDMarshaller.generateXsd(expandedSpec, outputStream);
    109109    }
    110110
    111111    protected static void writeXml(CMDComponentSpec spec, OutputStream outputStream) {
    112         try {
    113             MDMarshaller.marshal(spec, outputStream);
    114         } catch (UnsupportedEncodingException e) {
    115             LOG.error("Error in encoding: ", e);
    116         } catch (JAXBException e) {
    117             LOG.error("Cannot marshall spec: " + spec, e);
    118         }
     112        try {
     113            MDMarshaller.marshal(spec, outputStream);
     114        } catch (UnsupportedEncodingException e) {
     115            LOG.error("Error in encoding: ", e);
     116        } catch (JAXBException e) {
     117            LOG.error("Cannot marshall spec: " + spec, e);
     118        }
    119119    }
    120120
    121121    protected void checkStillUsed(String componentId) throws DeleteFailedException, ComponentRegistryException {
    122         List<ProfileDescription> profiles = getUsageInProfiles(componentId);
    123         List<ComponentDescription> components = getUsageInComponents(componentId);
    124         if (!profiles.isEmpty() || !components.isEmpty()) {
    125             throw new DeleteFailedException(createStillInUseMessage(profiles, components));
    126         }
    127     }
     122        for (ProfileDescription profileDescription : getProfileDescriptions()) {
     123            CMDComponentSpec spec = getMDProfile(profileDescription.getId());
     124            if (spec != null && findComponentId(componentId, spec.getCMDComponent())) {
     125                // Profile match - throw
     126                throw new DeleteFailedException("Component is still in use by other components or profiles. Request component usage for details.");
     127            }
     128        }
    128129
    129     private String createStillInUseMessage(List<ProfileDescription> profiles, List<ComponentDescription> components) {
    130         StringBuilder result = new StringBuilder();
    131         if (!profiles.isEmpty()) {
    132             result.append("Still used by the following profiles: \n");
    133             for (ProfileDescription profileDescription : profiles) {
    134                 result.append(" - ").append(profileDescription.getName()).append("\n");
    135             }
    136         }
    137         if (!components.isEmpty()) {
    138             result.append("Still used by the following components: \n");
    139             for (ComponentDescription componentDescription : components) {
    140                 result.append(" - ").append(componentDescription.getName()).append("\n");
    141             }
    142         }
    143         result.append("Try to change above mentioned references first.");
    144         return result.toString();
     130        for (ComponentDescription desc : getComponentDescriptions()) {
     131            CMDComponentSpec spec = getMDComponent(desc.getId());
     132            if (spec != null && findComponentId(componentId, spec.getCMDComponent())) {
     133                // Component match -> throw
     134                throw new DeleteFailedException("Component is still in use by one or more other components. Request component usage for details.");
     135            }
     136        }
    145137    }
    146138}
  • ComponentRegistry/trunk/ComponentRegistry/src/main/java/clarin/cmdi/componentregistry/rest/ComponentRegistryRestService.java

    r2541 r2556  
    267267    @Path("/components/usage/{componentId}")
    268268    @Produces({MediaType.TEXT_XML, MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON})
    269     public List<AbstractDescription> getComponentUsage(@PathParam("componentId") String componentId, @QueryParam(USERSPACE_PARAM) @DefaultValue("true") boolean userspace) throws ComponentRegistryException {
     269    public List<AbstractDescription> getComponentUsage(@PathParam("componentId") String componentId, @QueryParam(USERSPACE_PARAM) @DefaultValue("false") boolean userspace) throws ComponentRegistryException {
    270270        try {
    271271            final long start = System.currentTimeMillis();
     
    512512            registry.deleteMDComponent(componentId, principal, false);
    513513        } catch (DeleteFailedException e) {
    514             LOG.info("Component with id: " + componentId + " deletion failed.", e);
     514            LOG.info("Component with id: " + componentId + " deletion failed. Reason: " + e.getMessage());
     515            LOG.debug("Deletion failure details:", e);
    515516            return Response.status(Status.FORBIDDEN).entity("" + e.getMessage()).build();
    516517        } catch (ComponentRegistryException e) {
     
    522523        } catch (UserUnauthorizedException e) {
    523524            LOG.info("Component with id: " + componentId + " deletion failed: " + e.getMessage());
     525            LOG.debug("Deletion failure details:", e);
    524526            return Response.serverError().status(Status.UNAUTHORIZED).entity("" + e.getMessage()).build();
    525527        }
     
    10271029        final RssCreatorDescriptions instance = new RssCreatorDescriptions(userspace, getApplicationBaseURI(), "profiles", Integer.parseInt(limit), profiles, AbstractDescription.COMPARE_ON_DATE);
    10281030        final Rss rss = instance.getRss();
    1029         LOG.info("Releasing RSS of " + limit + " most recently registered profiles");
     1031        LOG.info("Releasing RSS of " + limit + " most recently registered profiles");
    10301032        return rss;
    10311033    }
  • ComponentRegistry/trunk/ComponentRegistry/src/test/java/clarin/cmdi/componentregistry/impl/database/ComponentRegistryDbImplTest.java

    r1992 r2556  
    348348    }
    349349
     350    @Test(expected=DeleteFailedException.class)
     351    public void testDoNotDeleteUsedComponent() throws Exception {
     352        RegistryUser user = createUser();
     353        ComponentRegistry register = getComponentRegistryForUser(null);
     354
     355        String comp1Id = "component1";
     356        String comp2Id = "component2";
     357
     358        String comp1Content = "";
     359        comp1Content += "<CMD_ComponentSpec isProfile=\"false\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n";
     360        comp1Content += "    xsi:noNamespaceSchemaLocation=\"general-component-schema.xsd\">\n";
     361        comp1Content += "    <Header/>\n";
     362        comp1Content += "    <CMD_Component name=\"Recursion\" CardinalityMin=\"1\" CardinalityMax=\"10\">\n";
     363        comp1Content += "       <CMD_Element name=\"Availability\" ValueScheme=\"string\" />\n";
     364        comp1Content += "    </CMD_Component>\n";
     365        comp1Content += "</CMD_ComponentSpec>\n";
     366
     367        ComponentDescription comp1Desc = RegistryTestHelper.addComponent(register, comp1Id, comp1Content);
     368
     369        // Component2 references component1
     370
     371        String comp2Content = "";
     372        comp2Content += "<CMD_ComponentSpec isProfile=\"false\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n";
     373        comp2Content += "    xsi:noNamespaceSchemaLocation=\"general-component-schema.xsd\">\n";
     374        comp2Content += "    <Header/>\n";
     375        comp2Content += "    <CMD_Component name=\"Recursion\" CardinalityMin=\"1\" CardinalityMax=\"10\">\n";
     376        comp2Content += "        <CMD_Element name=\"Availability\" ValueScheme=\"string\" />\n";
     377        comp2Content += "        <CMD_Component ComponentId=\"" + comp1Desc.getId() + "\" CardinalityMin=\"0\" CardinalityMax=\"5\"/>\n";
     378        comp2Content += "    </CMD_Component>\n";
     379        comp2Content += "</CMD_ComponentSpec>\n";
     380
     381        RegistryTestHelper.addComponent(register, comp2Id, comp2Content);
     382
     383        register.deleteMDComponent(comp1Desc.getId(), PRINCIPAL_ADMIN, false);
     384    }
     385
    350386    private ComponentDescription createComponent(ComponentRegistry registry) throws Exception {
    351387        ComponentDescription description = getComponentDesc();
  • ComponentRegistry/trunk/ComponentRegistry/src/test/java/clarin/cmdi/componentregistry/rest/ComponentRegistryRestServiceTest.java

    r2515 r2556  
    352352        assertEquals(Status.FORBIDDEN.getStatusCode(), response.getStatus());
    353353        assertEquals(
    354                 "Still used by the following profiles: \n - TestProfile3\nStill used by the following components: \n - YYY1\nTry to change above mentioned references first.",
     354                "Component is still in use by other components or profiles. Request component usage for details.",
    355355                response.getEntity(String.class));
    356356
Note: See TracChangeset for help on using the changeset viewer.