<commit_before>/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */
package de.kalpatec.pojosr.framework;

import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.util.ArrayList;
import java.util.Dictionary;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Properties;
import java.util.StringTokenizer;

import org.apache.felix.framework.ServiceRegistry;
import org.apache.felix.framework.util.EventDispatcher;
import org.apache.felix.framework.util.MapToDictionary;
import org.apache.felix.framework.util.StringMap;
import org.osgi.framework.Bundle;
import org.osgi.framework.BundleActivator;
import org.osgi.framework.BundleContext;
import org.osgi.framework.BundleEvent;
import org.osgi.framework.BundleException;
import org.osgi.framework.Constants;
import org.osgi.framework.ServiceReference;
import org.osgi.framework.Version;

class PojoSRBundle implements Bundle
{
    private final Revision m_revision;
    private final Map<String, String> m_manifest;
    private final Version m_version;
    private final String m_location;
    private final Map<Long, Bundle> m_bundles;
    private final ServiceRegistry m_reg;
    private final String m_activatorClass;
    private final long m_id;
    private final String m_symbolicName;
    private volatile BundleActivator m_activator = null;
    private volatile int m_state = Bundle.RESOLVED;
    private volatile BundleContext m_context = null;
    private final EventDispatcher m_dispatcher;
    private final ClassLoader m_loader;

    Revision getRevision()
    {
        return m_revision;
    }

    public PojoSRBundle(Revision revision, Map<String, String> manifest,
            Version version, String location, ServiceRegistry reg,
            EventDispatcher dispatcher, String activatorClass, long id,
            String symbolicName, Map<Long, Bundle> bundles, ClassLoader loader)
    {
        m_revision = revision;
        m_manifest = manifest;
        m_version = version;
        m_location = location;
        m_reg = reg;
        m_dispatcher = dispatcher;
        m_activatorClass = activatorClass;
        m_id = id;
        m_symbolicName = symbolicName;
        bundles.put(m_id, this);
        m_bundles = bundles;
        m_loader = loader;
    }

    public int getState()
    {
        return m_state;
    }

    public void start(int options) throws BundleException
    {
        // TODO: lifecycle - fix this
        start();
    }

    public synchronized void start() throws BundleException
    {
        if (m_state != Bundle.RESOLVED)
        {
            if (m_state == Bundle.ACTIVE)
            {
                return;
            }
            throw new BundleException("Bundle is in wrong state for start");
        }
        try
        {
            m_state = Bundle.STARTING;

            m_context = new PojoSRBundleContext(this, m_reg, m_dispatcher,
                    m_bundles);
            m_dispatcher.fireBundleEvent(new BundleEvent(BundleEvent.STARTING,
                    this));
            if (m_activatorClass != null)
            {
                m_activator = (BundleActivator) m_loader.loadClass(
                        m_activatorClass).newInstance();
                m_activator.start(m_context);
            }
            m_state = Bundle.ACTIVE;
            m_dispatcher.fireBundleEvent(new BundleEvent(BundleEvent.STARTED,
                    this));
        }
        catch (Throwable ex)
        {
            m_state = Bundle.RESOLVED;
            m_activator = null;
            m_dispatcher.fireBundleEvent(new BundleEvent(BundleEvent.STOPPED,
                    this));
            throw new BundleException("Unable to start bundle", ex);
        }
    }

    public void stop(int options) throws BundleException
    {
        // TODO: lifecycle - fix this
        stop();
    }

    public synchronized void stop() throws BundleException
    {
        if (m_state != Bundle.ACTIVE)
        {
            if (m_state == Bundle.RESOLVED)
            {
                return;
            }
            throw new BundleException("Bundle is in wrong state for stop");
        }
        try
        {
            m_state = Bundle.STOPPING;
            m_dispatcher.fireBundleEvent(new BundleEvent(BundleEvent.STOPPING,
                    this));
            if (m_activator != null)
            {
                m_activator.stop(m_context);
            }
        }
        catch (Throwable ex)
        {
            throw new BundleException("Error while stopping bundle", ex);
        }
        finally
        {
            m_reg.unregisterServices(this);
            m_dispatcher.removeListeners(this);
            m_activator = null;
            m_context = null;
            m_state = Bundle.RESOLVED;
            m_dispatcher.fireBundleEvent(new BundleEvent(BundleEvent.STOPPED,
                    this));
        }
    }

    public void update(InputStream input) throws BundleException
    {
        throw new BundleException("pojosr bundles can't be updated");
    }

    public void update() throws BundleException
    {
        throw new BundleException("pojosr bundles can't be updated");
    }

    public void uninstall() throws BundleException
    {
        throw new BundleException("pojosr bundles can't be uninstalled");
    }

    public Dictionary getHeaders()
    {
        return new MapToDictionary(m_manifest);
    }

    public long getBundleId()
    {
        return m_id;
    }

    public String getLocation()
    {
        return m_location;
    }

    public ServiceReference[] getRegisteredServices()
    {
        return m_reg.getRegisteredServices(this);
    }

    public ServiceReference[] getServicesInUse()
    {
        return m_reg.getServicesInUse(this);
    }

    public boolean hasPermission(Object permission)
    {
        // TODO: security - fix this
        return true;
    }

    public URL getResource(String name)
    {
        // TODO: module - implement this based on the revision
        URL result = m_loader.getResource(name);
        return result;
    }

    public Dictionary getHeaders(String locale)
    {
        return new MapToDictionary(getCurrentLocalizedHeader(locale));
    }

    Map getCurrentLocalizedHeader(String locale)
    {
        Map result = null;

        // Spec says empty local returns raw headers.
        if (locale.length() == 0)
        {
            result = new StringMap(m_manifest, false);
        }

        // If we have no result, try to get it from the cached headers.
        if (result == null)
        {
            synchronized (m_cachedHeaders)
            {
                // If the bundle is uninstalled, then the cached headers should
                // only contain the localized headers for the default locale at
                // the time of uninstall, so just return that.
                if (getState() == Bundle.UNINSTALLED)
                {
                    result = (Map) m_cachedHeaders.values().iterator().next();
                }
                // If the bundle has been updated, clear the cached headers.
                else if (getLastModified() > m_cachedHeadersTimestamp)
                {
                    m_cachedHeaders.clear();
                }
                // Otherwise, returned the cached headers if they exist.
                else
                {
                    // Check if headers for this locale have already been
                    // resolved
                    if (m_cachedHeaders.containsKey(locale))
                    {
                        result = (Map) m_cachedHeaders.get(locale);
                    }
                }
            }
        }

        // If the requested locale is not cached, then try to create it.
        if (result == null)
        {
            // Get a modifiable copy of the raw headers.
            Map headers = new StringMap(m_manifest, false);
            // Assume for now that this will be the result.
            result = headers;

            // Check to see if we actually need to localize anything
            boolean localize = false;
            for (Iterator it = headers.values().iterator(); !localize
                    && it.hasNext();)
            {
                if (((String) it.next()).startsWith("%"))
                {
                    localize = true;
                }
            }

            if (!localize)
            {
                // If localization is not needed, just cache the headers and
                // return
                // them as-is. Not sure if this is useful
                updateHeaderCache(locale, headers);
            }
            else
            {
                // Do localization here and return the localized headers
                String basename = (String) headers
                        .get(Constants.BUNDLE_LOCALIZATION);
                if (basename == null)
                {
                    basename = Constants.BUNDLE_LOCALIZATION_DEFAULT_BASENAME;
                }

                // Create ordered list of files to load properties from
                List resourceList = createLocalizationResourceList(basename,
                        locale);

                // Create a merged props file with all available props for this
                // locale
                boolean found = false;
                Properties mergedProperties = new Properties();
                for (Iterator it = resourceList.iterator(); it.hasNext();)
                {
                    URL temp = m_revision.getEntry(it.next() + ".properties");
                    if (temp != null)
                    {
                        found = true;
                        try
                        {
                            mergedProperties.load(temp.openConnection()
                                    .getInputStream());
                        }
                        catch (IOException ex)
                        {
                            // File doesn't exist, just continue loop
                        }
                    }
                }

                // If the specified locale was not found, then the spec says we
                // should
                // return the default localization.
                if (!found && !locale.equals(Locale.getDefault().toString()))
                {
                    result = getCurrentLocalizedHeader(Locale.getDefault()
                            .toString());
                }
                // Otherwise, perform the localization based on the discovered
                // properties and cache the result.
                else
                {
                    // Resolve all localized header entries
                    for (Iterator it = headers.entrySet().iterator(); it
                            .hasNext();)
                    {
                        Map.Entry entry = (Map.Entry) it.next();
                        String value = (String) entry.getValue();
                        if (value.startsWith("%"))
                        {
                            String newvalue;
                            String key = value
                                    .substring(value.indexOf("%") + 1);
                            newvalue = mergedProperties.getProperty(key);
                            if (newvalue == null)
                            {
                                newvalue = key;
                            }
                            entry.setValue(newvalue);
                        }
                    }

                    updateHeaderCache(locale, headers);
                }
            }
        }

        return result;
    }

    private void updateHeaderCache(String locale, Map localizedHeaders)
    {
        synchronized (m_cachedHeaders)
        {
            m_cachedHeaders.put(locale, localizedHeaders);
            m_cachedHeadersTimestamp = System.currentTimeMillis();
        }
    }

    private final Map m_cachedHeaders = new HashMap();
    private long m_cachedHeadersTimestamp;

    private static List createLocalizationResourceList(String basename,
            String locale)
    {
        List result = new ArrayList(4);

        StringTokenizer tokens;
        StringBuffer tempLocale = new StringBuffer(basename);

        result.add(tempLocale.toString());

        if (locale.length() > 0)
        {
            tokens = new StringTokenizer(locale, "_");
            while (tokens.hasMoreTokens())
            {
                tempLocale.append("_").append(tokens.nextToken());
                result.add(tempLocale.toString());
            }
        }
        return result;
    }

    public String getSymbolicName()
    {
        return m_symbolicName;
    }

    public Class loadClass(String name) throws ClassNotFoundException
    {
        return m_loader.loadClass(name);
    }

    public Enumeration getResources(String name) throws IOException
    {
        // TODO: module - implement this based on the revision
        return m_loader.getResources(name);
    }

    public Enumeration getEntryPaths(String path)
    {
        return new EntryFilterEnumeration(m_revision, false, path, null, false,
                true);
    }

    public URL getEntry(String path)
    {
        URL result = m_revision.getEntry(path);
        return result;
    }

    public long getLastModified()
    {
        return m_revision.getLastModified();
    }

    public Enumeration findEntries(String path, String filePattern,
            boolean recurse)
    {
        // TODO: module - implement this based on the revision
        return new EntryFilterEnumeration(m_revision, false, path, filePattern,
                recurse, true);
    }

    public BundleContext getBundleContext()
    {
        return m_context;
    }

    public Map getSignerCertificates(int signersType)
    {
        // TODO: security - fix this
        return new HashMap();
    }

    public Version getVersion()
    {
        return m_version;
    }

	public boolean equals(Object o) 
	{
	     if (o instanceof PojoSRBundle) {
		     return ((PojoSRBundle) o).m_id == m_id;
		 }
		 return false;
	}
}
<commit_msg>Implement manifest nl<commit_after>/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */
package de.kalpatec.pojosr.framework;

import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.util.ArrayList;
import java.util.Dictionary;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Properties;
import java.util.StringTokenizer;

import org.apache.felix.framework.ServiceRegistry;
import org.apache.felix.framework.util.EventDispatcher;
import org.apache.felix.framework.util.MapToDictionary;
import org.apache.felix.framework.util.StringMap;
import org.osgi.framework.Bundle;
import org.osgi.framework.BundleActivator;
import org.osgi.framework.BundleContext;
import org.osgi.framework.BundleEvent;
import org.osgi.framework.BundleException;
import org.osgi.framework.Constants;
import org.osgi.framework.ServiceReference;
import org.osgi.framework.Version;

class PojoSRBundle implements Bundle
{
    private final Revision m_revision;
    private final Map<String, String> m_manifest;
    private final Version m_version;
    private final String m_location;
    private final Map<Long, Bundle> m_bundles;
    private final ServiceRegistry m_reg;
    private final String m_activatorClass;
    private final long m_id;
    private final String m_symbolicName;
    private volatile BundleActivator m_activator = null;
    private volatile int m_state = Bundle.RESOLVED;
    private volatile BundleContext m_context = null;
    private final EventDispatcher m_dispatcher;
    private final ClassLoader m_loader;

    Revision getRevision()
    {
        return m_revision;
    }

    public PojoSRBundle(Revision revision, Map<String, String> manifest,
            Version version, String location, ServiceRegistry reg,
            EventDispatcher dispatcher, String activatorClass, long id,
            String symbolicName, Map<Long, Bundle> bundles, ClassLoader loader)
    {
        m_revision = revision;
        m_manifest = manifest;
        m_version = version;
        m_location = location;
        m_reg = reg;
        m_dispatcher = dispatcher;
        m_activatorClass = activatorClass;
        m_id = id;
        m_symbolicName = symbolicName;
        bundles.put(m_id, this);
        m_bundles = bundles;
        m_loader = loader;
    }

    public int getState()
    {
        return m_state;
    }

    public void start(int options) throws BundleException
    {
        // TODO: lifecycle - fix this
        start();
    }

    public synchronized void start() throws BundleException
    {
        if (m_state != Bundle.RESOLVED)
        {
            if (m_state == Bundle.ACTIVE)
            {
                return;
            }
            throw new BundleException("Bundle is in wrong state for start");
        }
        try
        {
            m_state = Bundle.STARTING;

            m_context = new PojoSRBundleContext(this, m_reg, m_dispatcher,
                    m_bundles);
            m_dispatcher.fireBundleEvent(new BundleEvent(BundleEvent.STARTING,
                    this));
            if (m_activatorClass != null)
            {
                m_activator = (BundleActivator) m_loader.loadClass(
                        m_activatorClass).newInstance();
                m_activator.start(m_context);
            }
            m_state = Bundle.ACTIVE;
            m_dispatcher.fireBundleEvent(new BundleEvent(BundleEvent.STARTED,
                    this));
        }
        catch (Throwable ex)
        {
            m_state = Bundle.RESOLVED;
            m_activator = null;
            m_dispatcher.fireBundleEvent(new BundleEvent(BundleEvent.STOPPED,
                    this));
            throw new BundleException("Unable to start bundle", ex);
        }
    }

    public void stop(int options) throws BundleException
    {
        // TODO: lifecycle - fix this
        stop();
    }

    public synchronized void stop() throws BundleException
    {
        if (m_state != Bundle.ACTIVE)
        {
            if (m_state == Bundle.RESOLVED)
            {
                return;
            }
            throw new BundleException("Bundle is in wrong state for stop");
        }
        try
        {
            m_state = Bundle.STOPPING;
            m_dispatcher.fireBundleEvent(new BundleEvent(BundleEvent.STOPPING,
                    this));
            if (m_activator != null)
            {
                m_activator.stop(m_context);
            }
        }
        catch (Throwable ex)
        {
            throw new BundleException("Error while stopping bundle", ex);
        }
        finally
        {
            m_reg.unregisterServices(this);
            m_dispatcher.removeListeners(this);
            m_activator = null;
            m_context = null;
            m_state = Bundle.RESOLVED;
            m_dispatcher.fireBundleEvent(new BundleEvent(BundleEvent.STOPPED,
                    this));
        }
    }

    public void update(InputStream input) throws BundleException
    {
        throw new BundleException("pojosr bundles can't be updated");
    }

    public void update() throws BundleException
    {
        throw new BundleException("pojosr bundles can't be updated");
    }

    public void uninstall() throws BundleException
    {
        throw new BundleException("pojosr bundles can't be uninstalled");
    }

    public Dictionary getHeaders()
    {
        return getHeaders(Locale.getDefault().toString());
    }

    public long getBundleId()
    {
        return m_id;
    }

    public String getLocation()
    {
        return m_location;
    }

    public ServiceReference[] getRegisteredServices()
    {
        return m_reg.getRegisteredServices(this);
    }

    public ServiceReference[] getServicesInUse()
    {
        return m_reg.getServicesInUse(this);
    }

    public boolean hasPermission(Object permission)
    {
        // TODO: security - fix this
        return true;
    }

    public URL getResource(String name)
    {
        // TODO: module - implement this based on the revision
        URL result = m_loader.getResource(name);
        return result;
    }

    public Dictionary getHeaders(String locale)
    {
        return new MapToDictionary(getCurrentLocalizedHeader(locale));
    }

    Map getCurrentLocalizedHeader(String locale)
    {
        Map result = null;

        // Spec says empty local returns raw headers.
        if (locale.length() == 0)
        {
            result = new StringMap(m_manifest, false);
        }

        // If we have no result, try to get it from the cached headers.
        if (result == null)
        {
            synchronized (m_cachedHeaders)
            {
                // If the bundle is uninstalled, then the cached headers should
                // only contain the localized headers for the default locale at
                // the time of uninstall, so just return that.
                if (getState() == Bundle.UNINSTALLED)
                {
                    result = (Map) m_cachedHeaders.values().iterator().next();
                }
                // If the bundle has been updated, clear the cached headers.
                else if (getLastModified() > m_cachedHeadersTimestamp)
                {
                    m_cachedHeaders.clear();
                }
                // Otherwise, returned the cached headers if they exist.
                else
                {
                    // Check if headers for this locale have already been
                    // resolved
                    if (m_cachedHeaders.containsKey(locale))
                    {
                        result = (Map) m_cachedHeaders.get(locale);
                    }
                }
            }
        }

        // If the requested locale is not cached, then try to create it.
        if (result == null)
        {
            // Get a modifiable copy of the raw headers.
            Map headers = new StringMap(m_manifest, false);
            // Assume for now that this will be the result.
            result = headers;

            // Check to see if we actually need to localize anything
            boolean localize = false;
            for (Iterator it = headers.values().iterator(); !localize
                    && it.hasNext();)
            {
                if (((String) it.next()).startsWith("%"))
                {
                    localize = true;
                }
            }

            if (!localize)
            {
                // If localization is not needed, just cache the headers and
                // return
                // them as-is. Not sure if this is useful
                updateHeaderCache(locale, headers);
            }
            else
            {
                // Do localization here and return the localized headers
                String basename = (String) headers
                        .get(Constants.BUNDLE_LOCALIZATION);
                if (basename == null)
                {
                    basename = Constants.BUNDLE_LOCALIZATION_DEFAULT_BASENAME;
                }

                // Create ordered list of files to load properties from
                List resourceList = createLocalizationResourceList(basename,
                        locale);

                // Create a merged props file with all available props for this
                // locale
                boolean found = false;
                Properties mergedProperties = new Properties();
                for (Iterator it = resourceList.iterator(); it.hasNext();)
                {
                    URL temp = m_revision.getEntry(it.next() + ".properties");
                    if (temp != null)
                    {
                        found = true;
                        try
                        {
                            mergedProperties.load(temp.openConnection()
                                    .getInputStream());
                        }
                        catch (IOException ex)
                        {
                            // File doesn't exist, just continue loop
                        }
                    }
                }

                // If the specified locale was not found, then the spec says we
                // should
                // return the default localization.
                if (!found && !locale.equals(Locale.getDefault().toString()))
                {
                    result = getCurrentLocalizedHeader(Locale.getDefault()
                            .toString());
                }
                // Otherwise, perform the localization based on the discovered
                // properties and cache the result.
                else
                {
                    // Resolve all localized header entries
                    for (Iterator it = headers.entrySet().iterator(); it
                            .hasNext();)
                    {
                        Map.Entry entry = (Map.Entry) it.next();
                        String value = (String) entry.getValue();
                        if (value.startsWith("%"))
                        {
                            String newvalue;
                            String key = value
                                    .substring(value.indexOf("%") + 1);
                            newvalue = mergedProperties.getProperty(key);
                            if (newvalue == null)
                            {
                                newvalue = key;
                            }
                            entry.setValue(newvalue);
                        }
                    }

                    updateHeaderCache(locale, headers);
                }
            }
        }

        return result;
    }

    private void updateHeaderCache(String locale, Map localizedHeaders)
    {
        synchronized (m_cachedHeaders)
        {
            m_cachedHeaders.put(locale, localizedHeaders);
            m_cachedHeadersTimestamp = System.currentTimeMillis();
        }
    }

    private final Map m_cachedHeaders = new HashMap();
    private long m_cachedHeadersTimestamp;

    private static List createLocalizationResourceList(String basename,
            String locale)
    {
        List result = new ArrayList(4);

        StringTokenizer tokens;
        StringBuffer tempLocale = new StringBuffer(basename);

        result.add(tempLocale.toString());

        if (locale.length() > 0)
        {
            tokens = new StringTokenizer(locale, "_");
            while (tokens.hasMoreTokens())
            {
                tempLocale.append("_").append(tokens.nextToken());
                result.add(tempLocale.toString());
            }
        }
        return result;
    }

    public String getSymbolicName()
    {
        return m_symbolicName;
    }

    public Class loadClass(String name) throws ClassNotFoundException
    {
        return m_loader.loadClass(name);
    }

    public Enumeration getResources(String name) throws IOException
    {
        // TODO: module - implement this based on the revision
        return m_loader.getResources(name);
    }

    public Enumeration getEntryPaths(String path)
    {
        return new EntryFilterEnumeration(m_revision, false, path, null, false,
                true);
    }

    public URL getEntry(String path)
    {
        URL result = m_revision.getEntry(path);
        return result;
    }

    public long getLastModified()
    {
        return m_revision.getLastModified();
    }

    public Enumeration findEntries(String path, String filePattern,
            boolean recurse)
    {
        // TODO: module - implement this based on the revision
        return new EntryFilterEnumeration(m_revision, false, path, filePattern,
                recurse, true);
    }

    public BundleContext getBundleContext()
    {
        return m_context;
    }

    public Map getSignerCertificates(int signersType)
    {
        // TODO: security - fix this
        return new HashMap();
    }

    public Version getVersion()
    {
        return m_version;
    }

	public boolean equals(Object o) 
	{
	     if (o instanceof PojoSRBundle) {
		     return ((PojoSRBundle) o).m_id == m_id;
		 }
		 return false;
	}
}

{'fraction_non_alphanumeric': 0.07554064378965551, 'fraction_numerical': 0.0005315084875261602, 'mean_word_length': 1.6010022464143772, 'pattern_counts': {'":': 0, '<': 11, '<?xml version=': 0, '>': 15, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 4, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4556544', 'n_tokens_mistral': 7590, 'n_tokens_neox': 7177, 'n_words': 2083}