/** Starts the factory. This method is not called when holding the monitor lock. */
 public void starting() {
   if (m_tracker == null) {
     if (m_requiredHandlers.size() != 0) {
       try {
         String filter =
             "(&("
                 + Handler.HANDLER_TYPE_PROPERTY
                 + "="
                 + PrimitiveHandler.HANDLER_TYPE
                 + ")"
                 + "(factory.state=1)"
                 + ")";
         m_tracker = new Tracker(m_context, m_context.createFilter(filter), this);
         m_tracker.open();
       } catch (InvalidSyntaxException e) {
         m_logger.log(
             Logger.ERROR,
             "A factory filter is not valid: "
                 + e.getMessage()); // Holding the lock should not be an issue here.
         stop();
       }
     }
   }
   // Else, the tracking has already started.
 }
 /** Handle the system notifying that it's ready to install configs. */
 public void checkReady() throws BootstrapFailure {
   if (requireRepository) {
     ServiceTracker repoTracker = null;
     try {
       if (repo == null) {
         Filter filter =
             ctx.createFilter(
                 "(" + Constants.OBJECTCLASS + "=" + RepoBootService.class.getName() + ")");
         repoTracker = new ServiceTracker(ctx, filter, null);
         repoTracker.open();
         logger.debug("Bootstrapping repository");
         RepoBootService rawRepo = (RepoBootService) repoTracker.waitForService(5000);
         if (rawRepo != null) {
           logger.debug("Bootstrap obtained repository");
           repo = rawRepo;
         } else {
           logger.info("Failed to bootstrap repo, returned null");
         }
       }
     } catch (InterruptedException ex) {
       logger.warn("Failed to bootstrap repo " + ex.getMessage(), ex);
     } catch (InvalidSyntaxException ex) {
       logger.warn("Failed to bootstrap repo " + ex.getMessage(), ex);
     } finally {
       if (repoTracker != null) {
         repoTracker.close();
       }
     }
     if (repo == null) {
       throw new BootstrapFailure(
           "Failed to acquire the bootstrap repository service to access configuration persistence.");
     }
   }
 }
 /**
  * Add a service listener.
  *
  * <p>This method is the same as calling {@link #addServiceListener(ServiceListener, String)} with
  * filter set to <code>null</code>.
  *
  * @see #addServiceListener(ServiceListener, String)
  */
 public void addServiceListener(ServiceListener listener) {
   try {
     addServiceListener(listener, null);
   } catch (InvalidSyntaxException e) {
     if (Debug.DEBUG_GENERAL) {
       Debug.println("InvalidSyntaxException w/ null filter" + e.getMessage()); // $NON-NLS-1$
       Debug.printStackTrace(e);
     }
   }
 }
  /**
   * Retrieves a reference to the Gibberish bundle, stops it and uninstalls it and then reinstalls
   * it in order to make sure that accounts are not reloaded once removed.
   *
   * @throws java.lang.Exception if something goes wrong while manipulating the bundles.
   */
  public void testAccountUninstallationPersistence() throws Exception {
    Bundle providerBundle = GibberishSlickFixture.providerBundle;

    providerBundle.stop();

    assertTrue(
        "Couldn't stop the protocol provider bundle. State was " + providerBundle.getState(),
        Bundle.ACTIVE != providerBundle.getState() && Bundle.STOPPING != providerBundle.getState());

    providerBundle.uninstall();

    assertEquals(
        "Couldn't stop the protocol provider bundle.",
        Bundle.UNINSTALLED,
        providerBundle.getState());

    // Now reinstall the bundle and restart the provider
    providerBundle = GibberishSlickFixture.bc.installBundle(providerBundle.getLocation());

    assertEquals(
        "Couldn't re-install protocol provider bundle.",
        Bundle.INSTALLED,
        providerBundle.getState());

    AccountManagerUtils.startBundleAndWaitStoredAccountsLoaded(
        GibberishSlickFixture.bc, providerBundle, "Gibberish");
    assertEquals(
        "Couldn't re-start protocol provider bundle.", Bundle.ACTIVE, providerBundle.getState());

    // verify that the provider is not reinstalled
    ServiceReference[] gibberishProviderRefs = null;
    try {
      gibberishProviderRefs =
          GibberishSlickFixture.bc.getServiceReferences(
              ProtocolProviderService.class.getName(),
              "(" + ProtocolProviderFactory.PROTOCOL + "=Gibberish)");
    } catch (InvalidSyntaxException ex) {
      fail("We apparently got our filter wrong " + ex.getMessage());
    }

    // make sure we didn't retrieve a service
    assertTrue(
        "A Gibberish Protocol Provider Service was still regged "
            + "as an osgi service after it was explicitly uninstalled",
        gibberishProviderRefs == null || gibberishProviderRefs.length == 0);

    // and a nasty hack at the end - delete the configuration file so that
    // we get a fresh start on next run.
    ServiceReference confReference =
        GibberishSlickFixture.bc.getServiceReference(ConfigurationService.class.getName());
    ConfigurationService configurationService =
        (ConfigurationService) GibberishSlickFixture.bc.getService(confReference);

    configurationService.purgeStoredConfiguration();
  }
 /**
  * fetchReferences.
  *
  * @return an array of {@link org.osgi.framework.ServiceReference} objects.
  */
 public ServiceReference<?>[] fetchReferences() {
   try {
     LOGGER.debug(
         "Try to locate a suitable service for objectClass = "
             + serviceInterface
             + " and filter = "
             + filterString);
     return bundleContext.getAllServiceReferences(serviceInterface, filterString);
   } catch (InvalidSyntaxException e) {
     LOGGER.error("Creation of filter failed: {}", e.getMessage(), e);
     throw new RuntimeException("Creation of filter failed", e);
   }
 }
  private IBackendService getBackendService() {
    ServiceReference[] references = null;
    try {
      references =
          Activator.getBundleContext()
              .getAllServiceReferences(IBackendService.class.getName(), null);
    } catch (InvalidSyntaxException e) {
      log.error(e.getMessage());
    }

    if ((references == null) || (references.length == 0)) {
      return null;
    }

    return (IBackendService) Activator.getBundleContext().getService(references[0]);
  }
  /** Uinstalls our test account and makes sure it really has been removed. */
  public void testUninstallAccount() {
    assertFalse(
        "No installed accounts found", fixture.providerFactory.getRegisteredAccounts().isEmpty());

    assertNotNull(
        "Found no provider corresponding to URI " + fixture.userID1,
        fixture.providerFactory.getProviderForAccount(fixture.provider1.getAccountID()));

    assertTrue(
        "Failed to remove a provider corresponding to URI " + fixture.userID1,
        fixture.providerFactory.uninstallAccount(fixture.provider1.getAccountID()));
    assertTrue(
        "Failed to remove a provider corresponding to URI " + fixture.userID1,
        fixture.providerFactory.uninstallAccount(fixture.provider2.getAccountID()));

    // make sure no providers have remained installed.
    ServiceReference[] sipProviderRefs = null;
    try {
      sipProviderRefs =
          fixture.bc.getServiceReferences(
              ProtocolProviderService.class.getName(),
              "(" + ProtocolProviderFactory.PROTOCOL + "=" + ProtocolNames.SIP + ")");
    } catch (InvalidSyntaxException ex) {
      fail("We apparently got our filter wrong " + ex.getMessage());
    }

    // make sure we didn't see a service
    assertTrue(
        "A Protocol Provider Service was still regged as an osgi "
            + "service for SIP URI:"
            + fixture.userID1
            + "After it was explicitly uninstalled",
        sipProviderRefs == null || sipProviderRefs.length == 0);

    // verify that the provider factory knows that we have uninstalled the
    // provider.
    assertTrue(
        "The SIP provider factory kept a reference to the provider we just "
            + "uninstalled (uri="
            + fixture.userID1
            + ")",
        fixture.providerFactory.getRegisteredAccounts().isEmpty()
            && fixture.providerFactory.getProviderForAccount(fixture.provider1.getAccountID())
                == null);
  }
  /**
   * Constructor for configuration resource manager
   *
   * @param configAdmin {@code ConfigurationAdmin}
   */
  public ConfigAdminResourceManager(Object configAdmin) {
    super(CONFIG_PATH);
    this.m_configAdmin = (ConfigurationAdmin) configAdmin;
    this.m_configListener = new ConfigurationListenerHandler();
    setRelations(
        new DefaultRelation(
            getPath(),
            Action.CREATE,
            "create",
            new DefaultParameter()
                .name(BUNDLE_LOCATION)
                .description("bundle location")
                .type(String.class)
                .optional(false),
            new DefaultParameter()
                .name(PID)
                .description("Persistent id of configuration")
                .type(String.class)
                .optional(true),
            new DefaultParameter()
                .name(FACTORY_PID)
                .description("Persistent id of factory pid")
                .type(String.class)
                .optional(true)));

    try {
      Configuration[] configs = m_configAdmin.listConfigurations(null);
      if (configs != null) {
        for (Configuration cfg : configs) {
          m_configurationResourceMap.put(cfg.getPid(), new ConfigurationResource(cfg));
        }
      }
    } catch (IOException e) {
      // well, this may happen..
      throw new RuntimeException(e.getMessage());
    } catch (InvalidSyntaxException e) {
      // should never happen..
      throw new RuntimeException(e.getMessage());
    }
  }
  @Override
  protected void doInit() throws Exception {
    final String filterStr = getApplicationContext().getInitProperties().get("filter");
    if (null != filterStr) {
      try {
        filter = FrameworkUtil.createFilter(filterStr);
      } catch (final InvalidSyntaxException e) {
        throw new IllegalArgumentException(
            String.format(
                "The specified filter '%s' is invalid. Please check the application configuration. %s",
                filterStr, e.getMessage()),
            e);
      }
    }

    final Dictionary<String, Object> props =
        new Hashtable<String, Object>(getApplicationContext().getInitProperties());

    if (null == props.get(Constants.SERVICE_DESCRIPTION)) {
      props.put(Constants.SERVICE_DESCRIPTION, "Gyrex web application based OSGi HttpService");
    }
    if (null == props.get(Constants.SERVICE_VENDOR)) {
      props.put(Constants.SERVICE_VENDOR, "Eclipse Gyrex");
    }
    if (null == props.get(Constants.SERVICE_PID)) {
      props.put(
          Constants.SERVICE_PID, HttpActivator.SYMBOLIC_NAME.concat(".service-").concat(getId()));
    }

    serviceRegistration =
        HttpActivator.getInstance()
            .getBundle()
            .getBundleContext()
            .registerService(
                new String[] {HttpService.class.getName(), ExtendedHttpService.class.getName()},
                this,
                props);
  }
 /**
  * Creates an OSGi filter for the classes.
  *
  * @param bundleContext a bundle context
  * @param classes array of tracked classes
  * @return osgi filter
  */
 private static Filter createFilter(final BundleContext bundleContext, final Class... classes) {
   final StringBuilder filter = new StringBuilder();
   if (classes != null) {
     if (classes.length > 1) {
       filter.append("(|");
     }
     for (Class clazz : classes) {
       filter
           .append("(")
           .append(Constants.OBJECTCLASS)
           .append("=")
           .append(clazz.getName())
           .append(")");
     }
     if (classes.length > 1) {
       filter.append(")");
     }
   }
   try {
     return bundleContext.createFilter(filter.toString());
   } catch (InvalidSyntaxException e) {
     throw new IllegalArgumentException("Unexpected InvalidSyntaxException: " + e.getMessage());
   }
 }
  /**
   * Stops and removes the tested bundle, verifies that it has unregistered its provider, then
   * reloads and restarts the bundle and verifies that the protocol provider is reRegistered in the
   * bundle context.
   *
   * @throws java.lang.Exception if an exception occurs during testing.
   */
  public void testInstallationPersistency() throws Exception {
    Bundle providerBundle = fixture.findProtocolProviderBundle(fixture.provider1);

    // set the global providerBundle reference that we will be using
    // in the last series of tests (Account uninstallation persistency)
    SipSlickFixture.providerBundle = providerBundle;

    assertNotNull("Couldn't find a bundle for the tested provider", providerBundle);

    providerBundle.stop();

    assertTrue(
        "Couldn't stop the protocol provider bundle. State was " + providerBundle.getState(),
        Bundle.ACTIVE != providerBundle.getState() && Bundle.STOPPING != providerBundle.getState());

    providerBundle.uninstall();

    assertEquals(
        "Couldn't stop the protocol provider bundle.",
        Bundle.UNINSTALLED,
        providerBundle.getState());

    // verify that the provider is no longer available
    ServiceReference[] sipProviderRefs = null;
    try {
      sipProviderRefs =
          fixture.bc.getServiceReferences(
              ProtocolProviderService.class.getName(),
              "(&"
                  + "("
                  + ProtocolProviderFactory.PROTOCOL
                  + "="
                  + ProtocolNames.SIP
                  + ")"
                  + "("
                  + ProtocolProviderFactory.USER_ID
                  + "="
                  + fixture.userID1
                  + ")"
                  + ")");
    } catch (InvalidSyntaxException ex) {
      fail("We apparently got our filter wrong: " + ex.getMessage());
    }

    // make sure we didn't see a service
    assertTrue(
        "A Protocol Provider Service was still regged as an osgi service "
            + "for SIP URI:"
            + fixture.userID1
            + "After it was explicitly uninstalled",
        sipProviderRefs == null || sipProviderRefs.length == 0);

    // verify that the provider factory knows that we have uninstalled the
    // provider.
    assertTrue(
        "The SIP provider factory kept a reference to the provider we just "
            + "uninstalled (uri="
            + fixture.userID1
            + ")",
        fixture.providerFactory.getRegisteredAccounts().isEmpty()
            && fixture.providerFactory.getProviderForAccount(fixture.provider1.getAccountID())
                == null);

    // Now reinstall the bundle
    providerBundle = fixture.bc.installBundle(providerBundle.getLocation());

    // set the global providerBundle reference that we will be using
    // in the last series of tests (Account uninstallation persistency)
    SipSlickFixture.providerBundle = providerBundle;

    assertEquals(
        "Couldn't re-install protocol provider bundle.",
        Bundle.INSTALLED,
        providerBundle.getState());

    AccountManagerUtils.startBundleAndWaitStoredAccountsLoaded(
        fixture.bc, providerBundle, ProtocolNames.SIP);
    assertEquals(
        "Couldn't re-start protocol provider bundle.", Bundle.ACTIVE, providerBundle.getState());

    // Make sure that the provider is there again.
    // verify that the provider is no longer available
    try {
      sipProviderRefs =
          fixture.bc.getServiceReferences(
              ProtocolProviderService.class.getName(),
              "(&"
                  + "("
                  + ProtocolProviderFactory.PROTOCOL
                  + "="
                  + ProtocolNames.SIP
                  + ")"
                  + "("
                  + ProtocolProviderFactory.USER_ID
                  + "="
                  + fixture.userID1
                  + ")"
                  + ")");
    } catch (InvalidSyntaxException ex) {
      fail("We apparently got our filter wrong " + ex.getMessage());
    }

    // make sure we didn't see a service
    assertTrue(
        "A Protocol Provider Service was not restored after being"
            + "reinstalled. SIP URI:"
            + fixture.userID1,
        sipProviderRefs != null && sipProviderRefs.length > 0);

    ServiceReference[] sipFactoryRefs = null;
    try {
      sipFactoryRefs =
          fixture.bc.getServiceReferences(
              ProtocolProviderFactory.class.getName(),
              "(" + ProtocolProviderFactory.PROTOCOL + "=" + ProtocolNames.SIP + ")");
    } catch (InvalidSyntaxException ex) {
      fail("We apparently got our filter wrong " + ex.getMessage());
    }

    // we're the ones who've reinstalled the factory so it's our
    // responsibility to update the fixture.
    fixture.providerFactory = (ProtocolProviderFactory) fixture.bc.getService(sipFactoryRefs[0]);
    fixture.provider1 = (ProtocolProviderService) fixture.bc.getService(sipProviderRefs[0]);

    // verify that the provider is also restored in the provider factory
    // itself
    assertTrue(
        "The SIP provider did not restore its own reference to the provider "
            + "that we just reinstalled (URI="
            + fixture.userID1
            + ")",
        !fixture.providerFactory.getRegisteredAccounts().isEmpty()
            && fixture.providerFactory.getProviderForAccount(fixture.provider1.getAccountID())
                != null);
  }
  private void importSettingsCSV(Reader in, final ImportCallback callback) throws IOException {
    final ICsvBeanReader reader = new CsvBeanReader(in, CsvPreference.STANDARD_PREFERENCE);
    final CellProcessor[] processors =
        new CellProcessor[] {
          null,
          new ConvertNullTo(""),
          null,
          new CellProcessor() {

            @Override
            public Object execute(Object arg, CsvContext ctx) {
              Set<net.solarnetwork.node.Setting.SettingFlag> set = null;
              if (arg != null) {
                int mask = Integer.parseInt(arg.toString());
                set = net.solarnetwork.node.Setting.SettingFlag.setForMask(mask);
              }
              return set;
            }
          },
          new org.supercsv.cellprocessor.ParseDate(SETTING_MODIFIED_DATE_FORMAT)
        };
    reader.getHeader(true);
    final List<Setting> importedSettings = new ArrayList<Setting>();
    transactionTemplate.execute(
        new TransactionCallbackWithoutResult() {

          @Override
          protected void doInTransactionWithoutResult(final TransactionStatus status) {
            Setting s;
            try {
              while ((s = reader.read(Setting.class, CSV_HEADERS, processors)) != null) {
                if (!callback.shouldImportSetting(s)) {
                  continue;
                }
                if (s.getKey() == null) {
                  continue;
                }
                if (s.getValue() == null) {
                  settingDao.deleteSetting(s.getKey(), s.getType());
                } else {
                  settingDao.storeSetting(s);
                  importedSettings.add(s);
                }
              }
            } catch (IOException e) {
              log.error("Unable to import settings: {}", e.getMessage());
              status.setRollbackOnly();
            } finally {
              try {
                reader.close();
              } catch (IOException e) {
                // ingore
              }
              if (status.isRollbackOnly()) {
                importedSettings.clear();
              }
            }
          }
        });

    // now that settings have been imported into DAO layer, we need to apply them to the existing
    // runtime

    // first, determine what factories we have... these have keys like <factoryPID>.FACTORY
    final Map<String, Setting> factorySettings = new HashMap<String, Setting>();
    for (Setting s : importedSettings) {
      if (s.getKey() == null || !s.getKey().endsWith(FACTORY_SETTING_KEY_SUFFIX)) {
        continue;
      }
      String factoryPID =
          s.getKey().substring(0, s.getKey().length() - FACTORY_SETTING_KEY_SUFFIX.length());
      log.debug("Discovered imported factory setting {}", factoryPID);
      factorySettings.put(factoryPID, s);

      // Now create the CA configuration for all defined factories, to handle situation where we
      // don't actually
      // configure any custom settings on the factory. In that case we don't have any settings, but
      // we need
      // to instantiate the factory so we create a default instance.
      try {
        int instanceCount = Integer.valueOf(s.getValue());
        for (int i = 1; i <= instanceCount; i++) {
          String instanceKey = String.valueOf(i);
          Configuration conf = getConfiguration(factoryPID, instanceKey);
          @SuppressWarnings("unchecked")
          Dictionary<String, Object> props = conf.getProperties();
          if (props == null) {
            props = new Hashtable<String, Object>();
            props.put(OSGI_PROPERTY_KEY_FACTORY_INSTANCE_KEY, instanceKey);
            conf.update(props);
          }
        }
      } catch (NumberFormatException e) {
        log.warn(
            "Factory {} setting does not have instance count value: {}",
            factoryPID,
            e.getMessage());
      } catch (InvalidSyntaxException e) {
        log.warn("Factory {} setting has invalid syntax: {}", factoryPID, e.getMessage());
      }
    }

    // now convert imported settings into a SettingsCommand, so values are applied to Configuration
    // Admin
    SettingsCommand cmd = new SettingsCommand();

    for (Setting s : importedSettings) {
      if (s.getKey() == null) {
        continue;
      }

      // skip factory instance definitions
      if (s.getKey().endsWith(FACTORY_SETTING_KEY_SUFFIX)) {
        continue;
      }

      // skip things that don't look like CA settings
      if (!CA_PID_PATTERN.matcher(s.getKey()).matches()
          || s.getType() == null
          || SetupSettings.SETUP_TYPE_KEY.equals(s.getType())
          || s.getType().length() < 1) {
        continue;
      }

      SettingValueBean bean = new SettingValueBean();

      // find out if this is a factory
      for (String factoryPID : factorySettings.keySet()) {
        if (s.getKey().startsWith(factoryPID + ".")
            && s.getKey().length() > (factoryPID.length() + 1)) {
          bean.setProviderKey(factoryPID);
          bean.setInstanceKey(s.getKey().substring(factoryPID.length() + 1));
          break;
        }
      }

      if (bean.getProviderKey() == null) {
        // not a factory setting
        bean.setProviderKey(s.getKey());
      }
      bean.setKey(s.getType());
      bean.setValue(s.getValue());
      bean.setTransient(s.getFlags() != null && s.getFlags().contains(SettingFlag.Volatile));
      cmd.getValues().add(bean);
    }
    if (cmd.getValues().size() > 0) {
      updateSettings(cmd);
    }
  }