private String loadVanityPath()

in src/main/java/org/apache/sling/resourceresolver/impl/mapping/VanityPathHandler.java [523:632]


    private String loadVanityPath(
            final Resource resource,
            final Map<String, List<MapEntry>> entryMap,
            final Map<String, List<String>> targetPaths,
            boolean addToCache,
            boolean updateCounter) {

        if (!isValidVanityPath(resource.getPath())) {
            return null;
        }

        final ValueMap props = resource.getValueMap();
        long vanityOrder = props.get(PROP_VANITY_ORDER, 0L);

        // url is ignoring scheme and host.port and the path is
        // what is stored in the sling:vanityPath property
        boolean hasVanityPath = false;
        final String[] pVanityPaths = props.get(PROP_VANITY_PATH, new String[0]);
        if (log.isTraceEnabled()) {
            log.trace("vanity paths on {}: {}", resource.getPath(), Arrays.asList(pVanityPaths));
        }

        for (final String pVanityPath : pVanityPaths) {
            final String[] result = this.getVanityPathDefinition(resource.getPath(), pVanityPath);
            if (result != null) {
                // redirect target is the node providing the sling:vanityPath
                // property (or its parent if the node is called jcr:content)
                final Resource redirectTarget;
                if (JCR_CONTENT.equals(resource.getName())) {
                    redirectTarget = resource.getParent();
                    if (redirectTarget == null) {
                        // we encountered a broken resource jcr:content resource
                        // that apparently has no parent; skip this one and
                        // continue with next
                        log.warn("containingResource is null for vanity path on {}, skipping.", resource.getPath());
                        continue;
                    }
                } else {
                    redirectTarget = resource;
                }

                hasVanityPath = true;
                final String url = result[0] + result[1];
                final String redirect = redirectTarget.getPath();
                final String redirectName = redirectTarget.getName();

                // whether the target is attained by an external redirect or
                // by an internal redirect is defined by the sling:redirect
                // property
                final int httpStatus = props.get(PROP_REDIRECT_EXTERNAL, false)
                        ? props.get(
                                PROP_REDIRECT_EXTERNAL_REDIRECT_STATUS, factory.getDefaultVanityPathRedirectStatus())
                        : -1;

                final String checkPath = result[1];

                if (addToCache) {
                    MapEntry entry1;
                    MapEntry entry2;

                    if (redirectName.contains(".")) {
                        // name with extension
                        String extension = redirectName.substring(redirectName.lastIndexOf('.') + 1);

                        // 1. entry with exact match
                        entry1 = createMapEntry(url + "$", httpStatus, vanityOrder, redirect);

                        // 2. entry with extension
                        // ("\\." matches a single dot)
                        entry2 = createMapEntry(url + "\\." + extension, httpStatus, vanityOrder, redirect);
                    } else {
                        // name without extension

                        // 1. entry with exact match
                        entry1 = createMapEntry(url + "$", httpStatus, vanityOrder, redirect + ".html");

                        // 2. entry with match supporting selectors and extension
                        // ("(\\..*)" matches a single dot followed by any characters)
                        entry2 = createMapEntry(url + "(\\..*)", httpStatus, vanityOrder, redirect + "$1");
                    }

                    int count = 0;

                    if (this.addEntry(entryMap, checkPath, entry1)) {
                        count += 1;
                    }

                    if (this.addEntry(entryMap, checkPath, entry2)) {
                        count += 1;
                    }

                    if (count > 0) {
                        // keep the path to return
                        this.updateTargetPaths(targetPaths, redirect, checkPath);

                        if (updateCounter) {
                            vanityCounter.addAndGet(count);
                        }

                        // update bloom filter
                        BloomFilterUtils.add(vanityBloomFilter, checkPath);
                    }
                } else {
                    // update bloom filter
                    BloomFilterUtils.add(vanityBloomFilter, checkPath);
                }
            }
        }
        return hasVanityPath ? pVanityPaths[0] : null;
    }