/*
(non-Javadoc)

@seenet.jawr.web.resource.bundle.handler.ResourceBundlesHandler#
getGlobalResourceBundlePaths
(net.jawr.web.resource.bundle.iterator.ConditionalCommentCallbackHandler,
java.lang.String)
504295
@Override
	public ResourceBundlePathsIterator getGlobalResourceBundlePaths(
			ConditionalCommentCallbackHandler commentCallbackHandler, Map<String, String> variants) {

		return getBundleIterator(getDebugMode(), globalBundles, commentCallbackHandler, variants);
	}
677374
@Override
    protected void setMessageResourceBundle(HttpServletRequest request, ResourceBundle bundle)
	{
		Config.set(request, Config.FMT_LOCALIZATION_CONTEXT, new LocalizationContext(bundle, request.getLocale()));
        LOGGER.debug("Enabled JSTL localization using: ", bundle);
        LOGGER.debug("Loaded resource bundle ", bundle, " as default bundle");
    }
392548
protected Loader<?> getTemplateLoaderForPath(String templateLoaderPath) {
        if (templateLoaderPath.startsWith(ResourceUtils.CLASSPATH_URL_PREFIX)) {
            String basePackagePath = templateLoaderPath.substring(ResourceUtils.CLASSPATH_URL_PREFIX.length());
            if (log.isDebugEnabled()) {
                log.debug("Template loader path [" + templateLoaderPath + "] resolved to class path [" + basePackagePath + "]");
            }
            ClasspathLoader loader = new ClasspathLoader(environment.getClassLoader());
            loader.setPrefix(basePackagePath);
            return loader;
        } else if (templateLoaderPath.startsWith(ResourceUtils.FILE_URL_PREFIX)) {
            File file = new File(templateLoaderPath.substring(ResourceUtils.FILE_URL_PREFIX.length()));
            String prefix = file.getAbsolutePath();
            if (log.isDebugEnabled()) {
                log.debug("Template loader path [" + templateLoaderPath + "] resolved to file path [" + prefix + "]");
            }
            FileLoader loader = new FileLoader();
            loader.setPrefix(prefix);
            return loader;
        } else {
            File file = new File(environment.getBasePath(), templateLoaderPath);
            String prefix = file.getAbsolutePath();
            if (log.isDebugEnabled()) {
                log.debug("Template loader path [" + templateLoaderPath + "] resolved to file path [" + prefix + "]");
            }
            FileLoader loader = new FileLoader();
            loader.setPrefix(prefix);
            return loader;
        }
    }
712403
private static NLS getNLS(Locale l, String resourceBundle, String statsType) {
        // init Locale
        boolean bDefaultLocale = false;
        if (l == null || l == Locale.getDefault()) {
            bDefaultLocale = true;
            l = Locale.getDefault();
        }

        NLS aNLS = null;
        if (resourceBundle == null) {
            // resourceBundle is NULL
            // trial 1: try prepending the 5.0 default resourcebundle location prefix (to support commerce, portal, etc.)
            // trial 2: if that fails return default 6.0 PMI resourcebundle
            int trial = 1;
            do {
                if (trial == 1)
                    resourceBundle = PMI_RESOURCE_BUNDLE_PREFIX_50 + statsType;
                else if (trial == 2)
                    resourceBundle = PMI_RESOURCE_BUNDLE;

                // 234782 - JPM: Check in NLS cache
                aNLS = (NLS) nlsMap.get(getNlsKey(resourceBundle, l));
                if (aNLS != null)
                    return aNLS;
                else
                    aNLS = new NLS(resourceBundle, l, true, false); // first time create 

                if (aNLS.isResourceLoaded())
                    break;

                ++trial;
            } while (trial <= 2);
        } else {
            // resourcebundle != null
            // Custom resource bundle
            // 234782 - JPM: Check in NLS cache
            aNLS = (NLS) nlsMap.get(getNlsKey(resourceBundle, l));
            if (aNLS != null)
                return aNLS;
            else
                aNLS = new NLS(resourceBundle, l, true, false); // first time create         

            // resourcebundle not loaded. so try using contextClassLoader to support
            // custom pmi in applications (war/ear file)
            // custom pmi resource bundle that is not found in the path
            // may its an application so use context classloader                                
            if (!aNLS.isResourceLoaded()) {
                // ------ security code
                final String _rbName = resourceBundle;
                final Locale _locale = l;

                try {
                    aNLS = (NLS)
                                    AccessController.doPrivileged(
                                                    new PrivilegedExceptionAction()
                                                    {
                                                        @Override
                                                        public Object run() throws Exception
                                                        {
                                                            return new NLS(_rbName, _locale, Thread.currentThread().getContextClassLoader());
                                                        }
                                                    });
                } catch (Exception e1) {
                    Tr.warning(tc, "PMI0030W", resourceBundle);
                    if (tc.isDebugEnabled())
                        Tr.debug(tc, "Error loading custom resource bundle using context classloader: " + e1.getMessage());
                }
                if (aNLS == null || !aNLS.isResourceLoaded()) {
                    aNLS = null;
                }
                // ------ security code
            }
        }
        // 234782 - JPM: Cache NLS object if successfully created
        if (aNLS != null && aNLS.isResourceLoaded()) {
            if (tc.isDebugEnabled())
                Tr.debug(tc, "Caching resource bundle: " + resourceBundle + " locale: " + l);

            // 234782 - JPM: Cache resourcebundle for this locale
            nlsMap.put(getNlsKey(resourceBundle, l), aNLS);
        }

        return aNLS;
    }
885008
@VisibleForTesting
    public FedoraResource getResourceFromPath(final String externalPath) {
        final Resource resource = translator().toDomain(externalPath);
        final FedoraResource fedoraResource = translator().convert(resource);

        if (fedoraResource instanceof Tombstone) {
            final String resourceURI = TRAILING_SLASH_REGEX.matcher(resource.getURI()).replaceAll("");
            throw new TombstoneException(fedoraResource, resourceURI + "/fcr:tombstone");
        }

        return fedoraResource;
    }
757191
@SuppressWarnings("deprecation")
  private ResourceBundle findResourceBundle(Object o) {
    ResourceBundle result = null;

    Parameters p = o.getClass().getAnnotation(Parameters.class);
    if (p != null && ! isEmpty(p.resourceBundle())) {
      result = ResourceBundle.getBundle(p.resourceBundle(), Locale.getDefault());
    } else {
      com.beust.jcommander.ResourceBundle a = o.getClass().getAnnotation(
          com.beust.jcommander.ResourceBundle.class);
      if (a != null && ! isEmpty(a.value())) {
        result = ResourceBundle.getBundle(a.value(), Locale.getDefault());
      }
    }

    return result;
  }
369137
private Set<String> getResourcePaths(List<JoinableResourceBundle> bundles) {

		Set<String> resourcePaths = new HashSet<>();

		for (JoinableResourceBundle bundle : bundles) {
			for (BundlePath bundlePath : bundle.getItemPathList()) {
				resourcePaths.add(bundlePath.getPath());
			}
		}

		return resourcePaths;
	}
1142247
@Override
    protected URL findResource(String name) {
        URL result = null;
        // Only check the parent bundle loader if the request is outside of "" or "/"
        if (!!!"".equals(name) && !!!"/".equals(name)) {
            // First try the bundleLoader
            result = bundleLoader.getResource(name);
        }
        // This doesn't have access to ALL split packages (it just gets one) so it's augmented with a resource provider  
        return result == null ? resourceProviders.findResource(name) : result;
    }
1307441
@Override
	public BundlePath nextPath() {

		BundlePath path = null;
		if (null == pathsIterator || !pathsIterator.hasNext()) {
			currentBundle = (JoinableResourceBundle) bundlesIterator.next();

			if (null != currentBundle.getExplorerConditionalExpression()) {
				commentCallbackHandler.openConditionalComment(currentBundle.getExplorerConditionalExpression());
			}

			if (StringUtils.isNotEmpty(currentBundle.getDebugURL())) {
				pathsIterator = Arrays
						.asList(new BundlePath(currentBundle.getBundlePrefix(), currentBundle.getDebugURL(), true))
						.iterator();
			} else {
				pathsIterator = currentBundle.getItemDebugPathList(variants).iterator();
			}
		}

		if (pathsIterator != null && pathsIterator.hasNext()) {
			path = pathsIterator.next();
		}

		return path;
	}
1014637
@Override
	public Set<String> getResourceNames(String path) {

		Set<String> resources = null;

		URL resourceURL = null;

		try {
			resourceURL = ClassLoaderResourceUtils.getResourceURL(getCompletePath(path), this);
			if (resourceURL.toString().startsWith(JAR_URL_PREFIX)) {
				resources = getResourceNamesFromJar(path, resourceURL);
			} else if (resourceURL.toString().startsWith(FILE_URL_PREFIX)) {

				String dirPath = resourceURL.getFile();
				File dir = new File(dirPath);
				resources = FileUtils.getResourceNames(dir);
			}
		} catch (ResourceNotFoundException e) {

			if (LOGGER.isDebugEnabled()) {
				LOGGER.debug("Unable to find resources name for path '" + path + "'", e);
			}
			resources = Collections.emptySet();
		}

		return resources;
	}
274932
@Override
  public @NotNull Set<String> getAllowedComponentsForTemplate(@NotNull String pageComponentPath, @NotNull ResourceResolver resolver) {
    Resource pageComponentResource = resolver.getResource(pageComponentPath);
    if (pageComponentResource != null) {
      Iterable<ParsysConfig> parSysConfigs = parsysConfigManager.getParsysConfigs(pageComponentResource.getPath(), resolver);

      SortedSet<String> allowedChildren = new TreeSet<>();
      for (ParsysConfig parSysConfig : parSysConfigs) {
        allowedChildren.addAll(parSysConfig.getAllowedChildren());
      }

      return allowedChildren;
    }
    // fallback
    return ImmutableSet.of();
  }
472202
private List<String> getGlobalBundleDependencies(GlobalPostProcessingContext ctx, List<String> excludedBundles) {
		List<JoinableResourceBundle> globalBundles = getRsBundlesHandler(ctx).getGlobalBundles();
		List<String> globalBundleDependencies = new ArrayList<>();
		for (JoinableResourceBundle globalBundle : globalBundles) {
			if (!excludedBundles.contains(globalBundle.getName())) {
				globalBundleDependencies.add(globalBundle.getName());
			}
		}
		return globalBundleDependencies;
	}
801783
private ResourcePaths.ResourcePath getPathInternal() {
        String resolvedPath;
        if (isPathAnnotationPresent()) {
            Path path = this.annotations.get(Path.class);
            if (isBlank(path.value())) {
                throw new IllegalArgumentException("The value of the @" + Path.class.getSimpleName() +
                        " annotation on " + field + " must not be empty");
            }
            resolvedPath = path.value();
        } else {
            resolvedPath = field.getName();
        }
        return path(resolvedPath);
    }
935505
@Override
	public ResourceBundlePathsIterator getGlobalResourceBundlePaths(DebugMode debugMode,
			ConditionalCommentCallbackHandler commentCallbackHandler, Map<String, String> variants) {

		return getBundleIterator(debugMode, globalBundles, commentCallbackHandler, variants);
	}
1175198
private static final String findStringWithFallback(String path,
            UResourceBundle actualBundle, UResourceBundle requested) {
        if (path.length() == 0) {
            return null;
        }
        if (!(actualBundle instanceof ICUResourceBundleImpl.ResourceContainer)) {
            return null;
        }
        if (requested == null) {
            requested = actualBundle;
        }

        ICUResourceBundle base = (ICUResourceBundle) actualBundle;
        ICUResourceBundleReader reader = base.wholeBundle.reader;
        int res = RES_BOGUS;

        // Collect existing and parsed key objects into an array of keys,
        // rather than assembling and parsing paths.
        int baseDepth = base.getResDepth();
        int depth = baseDepth;
        int numPathKeys = countPathKeys(path);
        assert numPathKeys > 0;
        String[] keys = new String[depth + numPathKeys];
        getResPathKeys(path, numPathKeys, keys, depth);

        for (;;) {  // Iterate over the parent bundles.
            for (;;) {  // Iterate over the keys on the requested path, within a bundle.
                ICUResourceBundleReader.Container readerContainer;
                if (res == RES_BOGUS) {
                    int type = base.getType();
                    if (type == TABLE || type == ARRAY) {
                        readerContainer = ((ICUResourceBundleImpl.ResourceContainer)base).value;
                    } else {
                        break;
                    }
                } else {
                    int type = ICUResourceBundleReader.RES_GET_TYPE(res);
                    if (ICUResourceBundleReader.URES_IS_TABLE(type)) {
                        readerContainer = reader.getTable(res);
                    } else if (ICUResourceBundleReader.URES_IS_ARRAY(type)) {
                        readerContainer = reader.getArray(res);
                    } else {
                        res = RES_BOGUS;
                        break;
                    }
                }
                String subKey = keys[depth++];
                res = readerContainer.getResource(reader, subKey);
                if (res == RES_BOGUS) {
                    --depth;
                    break;
                }
                ICUResourceBundle sub;
                if (ICUResourceBundleReader.RES_GET_TYPE(res) == ALIAS) {
                    base.getResPathKeys(keys, baseDepth);
                    sub = getAliasedResource(base, keys, depth, subKey, res, null, requested);
                } else {
                    sub = null;
                }
                if (depth == keys.length) {
                    // We found it.
                    if (sub != null) {
                        return sub.getString();  // string from alias handling
                    } else {
                        String s = reader.getString(res);
                        if (s == null) {
                            throw new UResourceTypeMismatchException("");
                        }
                        return s;
                    }
                }
                if (sub != null) {
                    base = sub;
                    reader = base.wholeBundle.reader;
                    res = RES_BOGUS;
                    // If we followed an alias, then we may have switched bundle (locale) and key path.
                    // Reserve space for the lower parts of the path according to the last-found resource.
                    // This relies on a resource found via alias to have its original location information,
                    // rather than the location of the alias.
                    baseDepth = base.getResDepth();
                    if (depth != baseDepth) {
                        String[] newKeys = new String[baseDepth + (keys.length - depth)];
                        System.arraycopy(keys, depth, newKeys, baseDepth, keys.length - depth);
                        keys = newKeys;
                        depth = baseDepth;
                    }
                }
            }
            // Try the parent bundle of the last-found resource.
            ICUResourceBundle nextBase = base.getParent();
            if (nextBase == null) {
                return null;
            }
            // We probably have not yet set the lower parts of the key path.
            base.getResPathKeys(keys, baseDepth);
            base = nextBase;
            reader = base.wholeBundle.reader;
            depth = baseDepth = 0;  // getParent() returned a top level table resource.
        }
    }
465248
protected ResourceBundle resolveBundle (HttpServletRequest req, String bundlePath,
                                            ClassLoader loader, boolean silent)
    {
        ResourceBundle bundle = null;

        if (req != null) {
            Enumeration<?> locales = req.getLocales();
            while (locales.hasMoreElements()) {
                Locale locale = (Locale)locales.nextElement();

                try {
                    // java caches resource bundles, so we don't need to reinvent the wheel here.
                    // however, java also falls back from a specific bundle to a more general one
                    // if it can't find a specific bundle. that's real nice of it, but we want
                    // first to see whether or not we have exact matches on any of the preferred
                    // locales specified by the client. if we don't, then we can rely on java's
                    // fallback mechanisms
                    bundle = ResourceBundle.getBundle(bundlePath, locale, loader);

                    // if it's an exact match, off we go
                    if (bundle.getLocale().equals(locale)) {
                        break;
                    }

                } catch (MissingResourceException mre) {
                    // no need to freak out quite yet, see if we have something for one of the
                    // other preferred locales
                }
            }
        }

        // if we were unable to find an exact match for any of the user's preferred locales, take
        // their most preferred and let java perform it's fallback logic on that one
        if (bundle == null) {
            Locale locale = (req == null) ? _deflocale : req.getLocale();
            try {
                bundle = ResourceBundle.getBundle(bundlePath, locale, loader);
            } catch (MissingResourceException mre) {
                if (!silent) {
                    // if we were unable even to find a default bundle, we may want to log a
                    // warning
                    log.warning("Unable to resolve any message bundle", "req", getURL(req),
                                "locale", locale, "bundlePath", bundlePath, "classLoader", loader,
                                "siteBundlePath", _siteBundlePath, "siteLoader", _siteLoader);
                }
            }
        }

        return bundle;
    }
568207
protected String getResourcePath(ParserContext parserContext) {
        if (parserContext != null) {
            try {
                Resource resource = parserContext.getReaderContext().getResource();
                return resource == null ? null : resource.getURL().getPath();
            } catch (IOException e) {}
        }
        
        return null;
    }