/** Tests the constructor. */
 @Test
 public void testConstructor() {
   final Citation citation = Citations.EPSG;
   PropertyAccessor accessor;
   assertNull(
       "No dummy interface expected.",
       PropertyAccessor.getType(citation.getClass(), "org.opengis.dummy"));
   accessor = createPropertyAccessor(citation);
   assertTrue("Count of 'get' methods.", accessor.count() >= 13);
 }
 /** Returns the names of all currently registered authorities. */
 public static synchronized Set<String> getAuthorityNames() {
   /*
    * IMPORTANT: Return the same Set instance (unmodifiable) as long as there is no change
    * in the list of registered factories, and create a new instance in case of changes.
    * 'add/removeAuthorityFactory(...)' and 'scanForPlugins()' methods reset 'authorityNames'
    * to null, which will cause the creation of a new Set instance. Some implementations like
    * AllAuthoritiesFactory rely on this behavior as a way to be notified of registration
    * changes for clearing their cache.
    */
   if (authorityNames == null) {
     authorityNames = new LinkedHashSet<String>();
     final Hints hints = EMPTY_HINTS;
     loop:
     for (int i = 0; ; i++) {
       final Set<? extends AuthorityFactory> factories;
       switch (i) {
         case 0:
           factories = getCRSAuthorityFactories(hints);
           break;
         case 1:
           factories = getCSAuthorityFactories(hints);
           break;
         case 2:
           factories = getDatumAuthorityFactories(hints);
           break;
         case 3:
           factories = getCoordinateOperationAuthorityFactories(hints);
           break;
         default:
           break loop;
       }
       for (final AuthorityFactory factory : factories) {
         final Citation authority = factory.getAuthority();
         if (authority != null) {
           authorityNames.add(Citations.getIdentifier(authority));
           for (final Identifier id : authority.getIdentifiers()) {
             authorityNames.add(id.getCode());
           }
         }
       }
     }
     authorityNames = Collections.unmodifiableSet(authorityNames);
   }
   return authorityNames;
 }
 /**
  * Returns {@code true} if this factory is available. The default implementation returns {@code
  * false} if no backing store were setup and {@link DeferredAuthorityFactory#createBackingStore}
  * throws an exception.
  */
 @Override
 synchronized boolean isAvailable() {
   try {
     return getBackingStore().isAvailable();
   } catch (FactoryNotFoundException exception) {
     /*
      * The factory is not available. This is error may be normal; it happens
      * for example if no gt2-epsg-hsql.jar (or similar JAR) are found in the
      * classpath, which is the case for example in GeoServer 1.3. Do not log
      * any stack trace,  since stack traces suggest more serious errors than
      * what we really have here.
      */
   } catch (FactoryException exception) {
     /*
      * The factory creation failed for an other reason, which may be more
      * serious. Now it is time to log a warning with a stack trace.
      */
     final Citation citation = getAuthority();
     final Collection titles = citation.getAlternateTitles();
     InternationalString title = citation.getTitle();
     if (titles != null) {
       for (final Iterator it = titles.iterator(); it.hasNext(); ) {
         /*
          * Uses the longuest title instead of the main one. In Geotools
          * implementation, the alternate title may contains usefull informations
          * like the EPSG database version number and the database engine.
          */
         final InternationalString candidate = (InternationalString) it.next();
         if (candidate.length() > title.length()) {
           title = candidate;
         }
       }
     }
     final LogRecord record =
         Loggings.format(Level.WARNING, LoggingKeys.UNAVAILABLE_AUTHORITY_FACTORY_$1, title);
     record.setSourceClassName(getClass().getName());
     record.setSourceMethodName("isAvailable");
     record.setThrown(exception);
     record.setLoggerName(LOGGER.getName());
     LOGGER.log(record);
   }
   return false;
 }
  /** Tests the set method. */
  @Test
  public void testSet() {
    Citation citation = new CitationImpl();
    final PropertyAccessor accessor = createPropertyAccessor(citation);

    // Tries with ISBN, which expect a String.
    Object value = "Random number";
    int index = accessor.indexOf("ISBN");
    assertTrue(index >= 0);
    assertNull(accessor.set(index, citation, value));
    assertSame(value, accessor.get(index, citation));
    assertSame(value, citation.getISBN());

    // Tries with the title. Automatic conversion from String to InternationalString expected.
    index = accessor.indexOf("title");
    assertTrue(index >= 0);
    assertNull(accessor.set(index, citation, "A random title"));
    value = accessor.get(index, citation);
    assertTrue(value instanceof InternationalString);
    assertEquals("A random title", value.toString());
    assertSame(value, citation.getTitle());

    // Tries with an element to be added in a collection.
    index = accessor.indexOf("alternateTitle");
    assertTrue(index >= 0);

    value = accessor.get(index, citation);
    assertTrue(value instanceof Collection);
    assertTrue(((Collection) value).isEmpty());

    value = accessor.set(index, citation, "An other title");
    assertTrue(value instanceof Collection);
    assertEquals(1, ((Collection) value).size());

    value = accessor.set(index, citation, "Yet an other title");
    assertTrue(value instanceof Collection);
    assertEquals(2, ((Collection) value).size());
  }
  /**
   * Test simple Record Marshalling.
   *
   * @throws java.lang.Exception
   */
  @Test
  public void inpsireExtensionUnmarshallingTest() throws Exception {

    String xml =
        "<wms:Capability xmlns:wms=\"http://www.opengis.net/wms\" xmlns:gml=\"http://www.opengis.net/gml/3.2\" xmlns:gmd=\"http://www.isotc211.org/2005/gmd\" xmlns:srv=\"http://www.isotc211.org/2005/srv\" xmlns:gco=\"http://www.isotc211.org/2005/gco\" xmlns:sld=\"http://www.opengis.net/sld\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" xmlns:inspire_vs=\"http://inspira.europa.eu/networkservice/view/1.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">"
            + '\n'
            + "    <inspire_vs:ExtendedCapabilities>"
            + '\n'
            + "        <inspire_vs:Resourcelocator>"
            + '\n'
            + "            <gmd:linkage>"
            + '\n'
            + "                <gmd:URL>http://javacestpasdlamenthealeau.com</gmd:URL>"
            + '\n'
            + "            </gmd:linkage>"
            + '\n'
            + "        </inspire_vs:Resourcelocator>"
            + '\n'
            + "        <inspire_vs:MetadataUrl>"
            + '\n'
            + "            <gmd:linkage>"
            + '\n'
            + "                <gmd:URL>http://javacestdurocknroll.com</gmd:URL>"
            + '\n'
            + "            </gmd:linkage>"
            + '\n'
            + "        </inspire_vs:MetadataUrl>"
            + '\n'
            + "        <inspire_vs:ResourceType>"
            + '\n'
            + "            <gmd:MD_ScopeCode codeList=\"http://schemas.opengis.net/iso/19139/20070417/resources/Codelist/gmxCodelists.xml#MD_ScopeCode\" codeListValue=\"service\"/>"
            + '\n'
            + "        </inspire_vs:ResourceType>"
            + '\n'
            + "        <inspire_vs:TemporalRefererence>"
            + '\n'
            + "            <gmd:EX_Extent>"
            + '\n'
            + "                <gmd:temporalElement>"
            + '\n'
            + "                    <gmd:EX_TemporalExtent>"
            + '\n'
            + "                        <gmd:extent>"
            + '\n'
            + "                            <gml:TimePeriod>"
            + '\n'
            + "                                <gml:beginPosition>1970-01-02T10:20:00+01:00</gml:beginPosition>"
            + '\n'
            + "                                <gml:endPosition>1970-01-02T10:20:01.000+01:00</gml:endPosition>"
            + '\n'
            + "                            </gml:TimePeriod>"
            + '\n'
            + "                        </gmd:extent>"
            + '\n'
            + "                    </gmd:EX_TemporalExtent>"
            + '\n'
            + "                </gmd:temporalElement>"
            + '\n'
            + "            </gmd:EX_Extent>"
            + '\n'
            + "        </inspire_vs:TemporalRefererence>"
            + '\n'
            + "        <inspire_vs:Conformity>"
            + '\n'
            + "            <gmd:DQ_ConformanceResult>"
            + '\n'
            + "                <gmd:specification>"
            + '\n'
            + "                    <gmd:CI_Citation>"
            + '\n'
            + "                        <gmd:title>"
            + '\n'
            + "                            <gco:CharacterString>European Petroleum Survey Group</gco:CharacterString>"
            + '\n'
            + "                        </gmd:title>"
            + '\n'
            + "                        <gmd:alternateTitle>"
            + '\n'
            + "                            <gco:CharacterString>EPSG</gco:CharacterString>"
            + '\n'
            + "                        </gmd:alternateTitle>"
            + '\n'
            + "                        <gmd:identifier>"
            + '\n'
            + "                            <gmd:MD_Identifier>"
            + '\n'
            + "                                <gmd:code>"
            + '\n'
            + "                                    <gco:CharacterString>EPSG</gco:CharacterString>"
            + '\n'
            + "                                </gmd:code>"
            + '\n'
            + "                            </gmd:MD_Identifier>"
            + '\n'
            + "                        </gmd:identifier>"
            + '\n'
            + "                        <gmd:citedResponsibleParty>"
            + '\n'
            + "                            <gmd:CI_ResponsibleParty>"
            + '\n'
            + "                                <gmd:organisationName>"
            + '\n'
            + "                                    <gco:CharacterString>European Petroleum Survey Group</gco:CharacterString>"
            + '\n'
            + "                                </gmd:organisationName>"
            + '\n'
            + "                                <gmd:contactInfo>"
            + '\n'
            + "                                    <gmd:CI_Contact>"
            + '\n'
            + "                                        <gmd:onlineResource>"
            + '\n'
            + "                                            <gmd:CI_OnlineResource>"
            + '\n'
            + "                                                <gmd:linkage>"
            + '\n'
            + "                                                    <gmd:URL>http://www.epsg.org</gmd:URL>"
            + '\n'
            + "                                                </gmd:linkage>"
            + '\n'
            + "                                                <gmd:function>"
            + '\n'
            + "                                                    <gmd:CI_OnLineFunctionCode codeList=\"http://schemas.opengis.net/iso/19139/20070417/resources/Codelist/gmxCodelists.xml#CI_OnLineFunctionCode\" codeListValue=\"information\"/>"
            + '\n'
            + "                                                </gmd:function>"
            + '\n'
            + "                                            </gmd:CI_OnlineResource>"
            + '\n'
            + "                                        </gmd:onlineResource>"
            + '\n'
            + "                                    </gmd:CI_Contact>"
            + '\n'
            + "                                </gmd:contactInfo>"
            + '\n'
            + "                                <gmd:role>"
            + '\n'
            + "                                    <gmd:CI_RoleCode codeList=\"http://schemas.opengis.net/iso/19139/20070417/resources/Codelist/gmxCodelists.xml#CI_RoleCode\" codeListValue=\"principalInvestigator\"/>"
            + '\n'
            + "                                </gmd:role>"
            + '\n'
            + "                            </gmd:CI_ResponsibleParty>"
            + '\n'
            + "                        </gmd:citedResponsibleParty>"
            + '\n'
            + "                        <gmd:presentationForm>"
            + '\n'
            + "                            <gmd:CI_PresentationFormCode codeList=\"http://schemas.opengis.net/iso/19139/20070417/resources/Codelist/gmxCodelists.xml#CI_PresentationFormCode\" codeListValue=\"tableDigital\"/>"
            + '\n'
            + "                        </gmd:presentationForm>"
            + '\n'
            + "                    </gmd:CI_Citation>"
            + '\n'
            + "                </gmd:specification>"
            + '\n'
            + "                <gmd:explanation>"
            + '\n'
            + "                    <gco:CharacterString>see the referenced specification</gco:CharacterString>"
            + '\n'
            + "                </gmd:explanation>"
            + '\n'
            + "                <gmd:pass>"
            + '\n'
            + "                    <gco:Boolean>true</gco:Boolean>"
            + '\n'
            + "                </gmd:pass>"
            + '\n'
            + "            </gmd:DQ_ConformanceResult>"
            + '\n'
            + "        </inspire_vs:Conformity>"
            + '\n'
            + "        <inspire_vs:MetadataPointOfContact>"
            + '\n'
            + "            <gmd:CI_ResponsibleParty>"
            + '\n'
            + "                <gmd:organisationName>"
            + '\n'
            + "                    <gco:CharacterString>European Petroleum Survey Group</gco:CharacterString>"
            + '\n'
            + "                </gmd:organisationName>"
            + '\n'
            + "                <gmd:contactInfo>"
            + '\n'
            + "                    <gmd:CI_Contact>"
            + '\n'
            + "                        <gmd:onlineResource>"
            + '\n'
            + "                            <gmd:CI_OnlineResource>"
            + '\n'
            + "                                <gmd:linkage>"
            + '\n'
            + "                                    <gmd:URL>http://www.epsg.org</gmd:URL>"
            + '\n'
            + "                                </gmd:linkage>"
            + '\n'
            + "                                <gmd:function>"
            + '\n'
            + "                                    <gmd:CI_OnLineFunctionCode codeList=\"http://schemas.opengis.net/iso/19139/20070417/resources/Codelist/gmxCodelists.xml#CI_OnLineFunctionCode\" codeListValue=\"information\"/>"
            + '\n'
            + "                                </gmd:function>"
            + '\n'
            + "                            </gmd:CI_OnlineResource>"
            + '\n'
            + "                        </gmd:onlineResource>"
            + '\n'
            + "                    </gmd:CI_Contact>"
            + '\n'
            + "                </gmd:contactInfo>"
            + '\n'
            + "                <gmd:role>"
            + '\n'
            + "                    <gmd:CI_RoleCode codeList=\"http://schemas.opengis.net/iso/19139/20070417/resources/Codelist/gmxCodelists.xml#CI_RoleCode\" codeListValue=\"principalInvestigator\"/>"
            + '\n'
            + "                </gmd:role>"
            + '\n'
            + "            </gmd:CI_ResponsibleParty>"
            + '\n'
            + "        </inspire_vs:MetadataPointOfContact>"
            + '\n'
            + "        <inspire_vs:MetadataDate>"
            + '\n'
            + "            <gco:Date>1970-01-02</gco:Date>"
            + '\n'
            + "        </inspire_vs:MetadataDate>"
            + '\n'
            + "        <inspire_vs:SpatialDataService>"
            + '\n'
            + "            <srv:serviceType>"
            + '\n'
            + "                <gco:LocalName>view</gco:LocalName>"
            + '\n'
            + "            </srv:serviceType>"
            + '\n'
            + "        </inspire_vs:SpatialDataService>"
            + '\n'
            + "        <inspire_vs:InpireKeywords>"
            + '\n'
            + "            <gmd:keyword>"
            + '\n'
            + "                <gco:CharacterString>something</gco:CharacterString>"
            + '\n'
            + "            </gmd:keyword>"
            + '\n'
            + "        </inspire_vs:InpireKeywords>"
            + '\n'
            + "        <inspire_vs:Languages>"
            + '\n'
            + "            <inspire_vs:Language>FR</inspire_vs:Language>"
            + '\n'
            + "            <inspire_vs:Language default=\"true\">EN</inspire_vs:Language>"
            + '\n'
            + "        </inspire_vs:Languages>"
            + '\n'
            + "        <inspire_vs:currentLanguage>FR</inspire_vs:currentLanguage>"
            + '\n'
            + "    </inspire_vs:ExtendedCapabilities>"
            + '\n'
            + "</wms:Capability>"
            + '\n';

    ExtendedCapabilitiesType ext = new ExtendedCapabilitiesType();
    NameFactory nameFactory = new DefaultNameFactory();
    ObjectFactory factory = new ObjectFactory();

    ext.setResourceType(ScopeCode.SERVICE);

    ext.setSpatialDataService(new ServiceType(nameFactory.createLocalName(null, "view")));

    ext.setResourcelocator(
        new DefaultOnlineResource(URI.create("http://javacestpasdlamenthealeau.com")));

    ext.setMetadataUrl(new DefaultOnlineResource(URI.create("http://javacestdurocknroll.com")));

    DefaultExtent extent = new DefaultExtent();
    DefaultTemporalExtent tempExt = new DefaultTemporalExtent();

    NamedIdentifier periodName = new NamedIdentifier(Citations.CRS, "period");
    final Map<String, Object> periodProp = new HashMap<>();
    periodProp.put(IdentifiedObject.NAME_KEY, periodName);
    NamedIdentifier instantName = new NamedIdentifier(Citations.CRS, "period instant");
    final Map<String, Object> properties = new HashMap<>();
    properties.put(IdentifiedObject.NAME_KEY, instantName);

    DefaultPeriod period =
        new DefaultPeriod(
            periodProp,
            new DefaultInstant(properties, new Date(120000000)),
            new DefaultInstant(properties, new Date(120001000)));

    tempExt.setExtent(period);
    extent.setTemporalElements(Arrays.asList(tempExt));
    ext.setTemporalRefererence(extent);

    DefaultResponsibleParty rp = new DefaultResponsibleParty(Role.PRINCIPAL_INVESTIGATOR);
    rp.setOrganisationName(new SimpleInternationalString("European Petroleum Survey Group"));
    DefaultOnlineResource or = new DefaultOnlineResource(URI.create("http://www.epsg.org"));
    or.setFunction(OnLineFunction.INFORMATION);
    DefaultContact ct = new DefaultContact(or);
    rp.setContactInfo(ct);
    DefaultCitation citation = new DefaultCitation();
    citation.setCitedResponsibleParties(Arrays.asList(rp));
    citation.setTitle(rp.getOrganisationName());
    citation.setAlternateTitles(Arrays.asList(new SimpleInternationalString("EPSG")));
    citation.setIdentifiers(Arrays.asList(new DefaultIdentifier("EPSG")));
    citation.setPresentationForms(Arrays.asList(PresentationForm.TABLE_DIGITAL));
    DefaultConformanceResult cresult =
        new DefaultConformanceResult(
            citation, new DefaultInternationalString("see the referenced specification"), true);
    ext.setConformity(cresult);

    ResponsibleParty party =
        DefaultResponsibleParty.castOrCopy(
            Citations.EPSG.getCitedResponsibleParties().iterator().next());
    ext.setMetadataPointOfContact(party);

    ext.setMetadataDate(new Date(82800000));

    DefaultKeywords key = new DefaultKeywords(new SimpleInternationalString("something"));
    ext.setInpireKeywords(key);

    List<LanguageType> langs = new ArrayList<>();
    langs.add(new LanguageType("FR"));
    langs.add(new LanguageType("EN", true));
    LanguagesType languages = new LanguagesType(langs);
    ext.setLanguages(languages);

    ext.setCurrentLanguage("FR");

    JAXBElement<ExtendedCapabilitiesType> jbExtendedCap = factory.createExtendedCapabilities(ext);
    Capability expResult = new Capability(null, null, null, jbExtendedCap);

    final Object unmarshalled = unmarshaller.unmarshal(new StringReader(xml));

    assertNotNull(unmarshalled);

    assertTrue(unmarshalled instanceof Capability);

    Capability result = (Capability) unmarshalled;

    // The Unmarshaller replaced automatically the DefaultInternationalString by a
    // SimpleInternationalString because it detected that there is only one locale.
    // Perform the same change in our expected result in order to allow comparison.
    cresult.setExplanation(new SimpleInternationalString(cresult.getExplanation().toString()));

    final ExtendedCapabilitiesType expCapabilities = expResult.getInspireExtendedCapabilities();
    final ExtendedCapabilitiesType capabilities = result.getInspireExtendedCapabilities();
    final ConformanceResult expConformity = expCapabilities.getConformity();
    final ConformanceResult conformity = capabilities.getConformity();
    final Citation expSpecification = expConformity.getSpecification();
    final Citation specification = conformity.getSpecification();
    final Extent expTemporal = expCapabilities.getTemporalRefererence();
    final Extent temporal = capabilities.getTemporalRefererence();
    final TemporalExtent expTemporalExtent = getSingleton(expTemporal.getTemporalElements());
    final TemporalExtent temporalExtent = getSingleton(temporal.getTemporalElements());
    final Period expExtentPeriod = (Period) expTemporalExtent.getExtent();
    final Period extentPeriod = (Period) temporalExtent.getExtent();

    assertEquals(expConformity.getExplanation().toString(), conformity.getExplanation().toString());
    assertEquals(expSpecification.getCollectiveTitle(), specification.getCollectiveTitle());
    assertEquals(
        expSpecification.getCitedResponsibleParties(), specification.getCitedResponsibleParties());
    assertEquals(expSpecification.getAlternateTitles(), specification.getAlternateTitles());
    assertEquals(expSpecification, specification);
    assertEquals(expConformity, conformity);
    assertEquals(expCapabilities.getResourceType(), capabilities.getResourceType());
    assertEquals(expTemporal.getDescription(), temporal.getDescription());
    assertEquals(expExtentPeriod.getBeginning().getDate(), extentPeriod.getBeginning().getDate());
    assertEquals(expExtentPeriod.getEnding().getDate(), extentPeriod.getEnding().getDate());
    if (expExtentPeriod.getClass() == extentPeriod.getClass()) {
      /*
       * The time period created by this test case is an instance of org.geotoolkit.temporal.object.DefaultPeriod
       * while the unmarshalled period is an instance of org.geotoolkit.gml.xml.v311.TimePeriodType. This is okay
       * since DefaultPeriod does not have JAXB annotation. But it prevents us to compare the objects further.
       */
      assertEquals(expExtentPeriod, extentPeriod);
      assertEquals(expTemporalExtent, temporalExtent);
      assertEquals(expTemporal, temporal);
      assertEquals(expCapabilities, capabilities);
      assertEquals(expResult, result);
    }
  }
 /** Creates a property accessor for the given citation. */
 private static PropertyAccessor createPropertyAccessor(final Citation citation) {
   final Class<?> implementation = citation.getClass();
   final Class<?> type = PropertyAccessor.getType(implementation, "org.opengis.metadata");
   assertNotNull(type);
   return new PropertyAccessor(implementation, type);
 }