1 package org.apache.archiva.indexer.search;
4 * Licensed to the Apache Software Foundation (ASF) under one
5 * or more contributor license agreements. See the NOTICE file
6 * distributed with this work for additional information
7 * regarding copyright ownership. The ASF licenses this file
8 * to you under the Apache License, Version 2.0 (the
9 * "License"); you may not use this file except in compliance
10 * with the License. You may obtain a copy of the License at
12 * http://www.apache.org/licenses/LICENSE-2.0
14 * Unless required by applicable law or agreed to in writing,
15 * software distributed under the License is distributed on an
16 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17 * KIND, either express or implied. See the License for the
18 * specific language governing permissions and limitations
23 import java.io.IOException;
24 import java.util.ArrayList;
25 import java.util.List;
27 import org.apache.commons.io.FileUtils;
28 import org.apache.maven.archiva.configuration.ArchivaConfiguration;
29 import org.apache.maven.archiva.configuration.Configuration;
30 import org.apache.maven.archiva.configuration.ManagedRepositoryConfiguration;
31 import org.codehaus.plexus.spring.PlexusInSpringTestCase;
32 import org.easymock.MockControl;
33 import org.sonatype.nexus.index.ArtifactContext;
34 import org.sonatype.nexus.index.ArtifactContextProducer;
35 import org.sonatype.nexus.index.NexusIndexer;
36 import org.sonatype.nexus.index.context.DefaultIndexingContext;
37 import org.sonatype.nexus.index.context.IndexingContext;
38 import org.sonatype.nexus.index.context.UnsupportedExistingLuceneIndexException;
39 import org.sonatype.nexus.index.IndexerEngine;
41 public class NexusRepositorySearchTest
42 extends PlexusInSpringTestCase
44 private RepositorySearch search;
46 private ArchivaConfiguration archivaConfig;
48 private NexusIndexer indexer;
50 private IndexingContext context;
52 private IndexerEngine indexerEngine;
54 private ArtifactContextProducer artifactContextProducer;
56 private MockControl archivaConfigControl;
58 private Configuration config;
60 private final static String TEST_REPO_1 = "nexus-search-test-repo";
62 private final static String TEST_REPO_2 = "nexus-search-test-repo-2";
65 protected void setUp()
70 indexer = (NexusIndexer) lookup( NexusIndexer.class );
72 archivaConfigControl = MockControl.createControl( ArchivaConfiguration.class );
74 archivaConfig = (ArchivaConfiguration) archivaConfigControl.getMock();
76 search = new NexusRepositorySearch( indexer, archivaConfig );
78 indexerEngine = (IndexerEngine) lookup( IndexerEngine.class );
80 artifactContextProducer = (ArtifactContextProducer) lookup( ArtifactContextProducer.class );
82 config = new Configuration();
83 config.addManagedRepository( createRepositoryConfig( TEST_REPO_1 ) );
84 config.addManagedRepository( createRepositoryConfig( TEST_REPO_2 ) );
87 private void createIndexForQuickSearch()
88 throws IOException, UnsupportedExistingLuceneIndexException
90 List<File> files = new ArrayList<File>();
91 files.add( new File( getBasedir(), "/target/test-classes/" + TEST_REPO_1 +
92 "/org/apache/archiva/archiva-search/1.0/archiva-search-1.0.jar" ) );
93 files.add( new File( getBasedir(), "/target/test-classes/" + TEST_REPO_1 +
94 "/org/apache/archiva/archiva-test/1.0/archiva-test-1.0.jar" ) );
95 files.add( new File( getBasedir(), "/target/test-classes/" + TEST_REPO_1 +
96 "/org/apache/archiva/archiva-test/2.0/archiva-test-2.0.jar" ) );
98 createIndex( TEST_REPO_1, files );
101 private ManagedRepositoryConfiguration createRepositoryConfig( String repository )
103 ManagedRepositoryConfiguration repositoryConfig = new ManagedRepositoryConfiguration();
104 repositoryConfig.setId( repository );
105 repositoryConfig.setLocation( getBasedir() + "/target/test-classes/" + repository );
106 repositoryConfig.setLayout( "default" );
107 repositoryConfig.setName( repository );
108 repositoryConfig.setScanned( true );
109 repositoryConfig.setSnapshots( false );
110 repositoryConfig.setReleases( true );
112 return repositoryConfig;
116 protected void tearDown()
119 FileUtils.deleteDirectory( new File( getBasedir(), "/target/test-classes/" + TEST_REPO_1 + "/.indexer" ) );
120 assertFalse( new File( getBasedir(), "/target/test-classes/" + TEST_REPO_1 + "/.indexer" ).exists() );
122 FileUtils.deleteDirectory( new File( getBasedir(), "/target/test-classes/" + TEST_REPO_2 + "/.indexer" ) );
123 assertFalse( new File( getBasedir(), "/target/test-classes/" + TEST_REPO_2 + "/.indexer" ).exists() );
128 private void createIndex( String repository, List<File> filesToBeIndexed )
129 throws IOException, UnsupportedExistingLuceneIndexException
131 context = new DefaultIndexingContext( repository, repository, new File( getBasedir(), "/target/test-classes/" +
132 repository ), new File( getBasedir(), "/target/test-classes/" + repository + "/.indexer" ), null, null,
133 NexusIndexer.FULL_INDEX, false );
134 //indexer.addIndexingContext( repository, repository, new File( getBasedir(), "/target/test-classes/" +
135 // repository ), new File( getBasedir(), "/target/test-classes/" + repository + "/.indexer" ), null, null,
136 // NexusIndexer.FULL_INDEX );
137 context.setSearchable( true );
139 //indexerEngine.beginIndexing( context );
141 for ( File artifactFile : filesToBeIndexed )
143 ArtifactContext ac = artifactContextProducer.getArtifactContext( context, artifactFile );
144 indexerEngine.index( context, ac );
147 context.close( false );
148 //indexerEngine.endIndexing( context );
149 //indexer.removeIndexingContext( context, false );
151 assertTrue( new File( getBasedir(), "/target/test-classes/" + repository + "/.indexer" ).exists() );
154 public void testQuickSearch()
157 createIndexForQuickSearch();
159 List<String> selectedRepos = new ArrayList<String>();
160 selectedRepos.add( TEST_REPO_1 );
163 archivaConfigControl.expectAndReturn( archivaConfig.getConfiguration(), config );
165 archivaConfigControl.replay();
167 SearchResults results = search.search( "user", selectedRepos, "archiva-search", null, null );
169 archivaConfigControl.verify();
171 assertNotNull( results );
172 assertEquals( 1, results.getTotalHits() );
174 SearchResultHit hit = results.getHits().get( 0 );
175 assertEquals( "org.apache.archiva", hit.getGroupId() );
176 assertEquals( "archiva-search", hit.getArtifactId() );
177 assertEquals( "1.0", hit.getVersions().get( 0 ) );
179 archivaConfigControl.reset();
182 archivaConfigControl.expectAndReturn( archivaConfig.getConfiguration(), config );
184 archivaConfigControl.replay();
186 results = search.search( "user", selectedRepos, "org.apache.archiva", null, null );
188 archivaConfigControl.verify();
190 assertNotNull( results );
191 assertEquals( 2, results.getTotalHits() );
193 //TODO: search for class & package names
196 public void testQuickSearchWithPagination()
199 createIndexForQuickSearch();
201 List<String> selectedRepos = new ArrayList<String>();
202 selectedRepos.add( TEST_REPO_1 );
205 SearchResultLimits limits = new SearchResultLimits( 0 );
206 limits.setPageSize( 1 );
208 archivaConfigControl.expectAndReturn( archivaConfig.getConfiguration(), config );
210 archivaConfigControl.replay();
212 SearchResults results = search.search( "user", selectedRepos, "org", limits, new ArrayList<String>() );
214 archivaConfigControl.verify();
216 assertNotNull( results );
217 assertEquals( 1, results.getHits().size() );
218 assertEquals( 2, results.getTotalHits() );
219 assertEquals( limits, results.getLimits() );
221 archivaConfigControl.reset();
224 limits = new SearchResultLimits( 1 );
225 limits.setPageSize( 1 );
227 archivaConfigControl.expectAndReturn( archivaConfig.getConfiguration(), config );
229 archivaConfigControl.replay();
231 results = search.search( "user", selectedRepos, "org", limits, null );
233 archivaConfigControl.verify();
235 assertNotNull( results );
236 assertEquals( 1, results.getHits().size() );
237 assertEquals( 2, results.getTotalHits() );
238 assertEquals( limits, results.getLimits() );
241 public void testArtifactFoundInMultipleRepositories()
244 createIndexForQuickSearch();
246 List<File> files = new ArrayList<File>();
247 files.add( new File( getBasedir(), "/target/test-classes/" + TEST_REPO_2 +
248 "/org/apache/archiva/archiva-search/1.0/archiva-search-1.0.jar" ) );
249 files.add( new File( getBasedir(), "/target/test-classes/" + TEST_REPO_2 +
250 "/org/apache/archiva/archiva-search/1.1/archiva-search-1.1.jar" ) );
251 createIndex( TEST_REPO_2, files );
253 List<String> selectedRepos = new ArrayList<String>();
254 selectedRepos.add( TEST_REPO_1 );
255 selectedRepos.add( TEST_REPO_2 );
257 config.addManagedRepository( createRepositoryConfig( TEST_REPO_2 ) );
259 archivaConfigControl.expectAndReturn( archivaConfig.getConfiguration(), config, 2 );
261 archivaConfigControl.replay();
263 SearchResults results = search.search( "user", selectedRepos, "archiva-search", null, null );
265 archivaConfigControl.verify();
267 assertNotNull( results );
268 assertEquals( 1, results.getTotalHits() );
270 SearchResultHit hit = results.getHits().get( 0 );
271 assertEquals( "org.apache.archiva", hit.getGroupId() );
272 assertEquals( "archiva-search", hit.getArtifactId() );
273 assertEquals( 2, hit.getVersions().size() );
274 assertTrue( hit.getVersions().contains( "1.0" ) );
275 assertTrue( hit.getVersions().contains( "1.1" ) );
277 archivaConfigControl.reset();
279 // TODO: [BROWSE] in artifact info from browse, display all the repositories where the artifact is found
282 public void testNoMatchFound()
285 createIndexForQuickSearch();
287 List<String> selectedRepos = new ArrayList<String>();
288 selectedRepos.add( TEST_REPO_1 );
290 archivaConfigControl.expectAndReturn( archivaConfig.getConfiguration(), config );
292 archivaConfigControl.replay();
294 SearchResults results = search.search( "user", selectedRepos, "dfghdfkweriuasndsaie", null, null );
296 archivaConfigControl.verify();
298 assertNotNull( results );
299 assertEquals( 0, results.getTotalHits() );
302 public void testNoIndexFound()
305 List<String> selectedRepos = new ArrayList<String>();
306 selectedRepos.add( TEST_REPO_1 );
308 archivaConfigControl.expectAndReturn( archivaConfig.getConfiguration(), config );
310 archivaConfigControl.replay();
312 SearchResults results = search.search( "user", selectedRepos, "org.apache.archiva", null, null );
313 assertNotNull( results );
314 assertEquals( 0, results.getTotalHits() );
316 archivaConfigControl.verify();
319 public void testRepositoryNotFound()
322 List<String> selectedRepos = new ArrayList<String>();
323 selectedRepos.add( "non-existing-repo" );
325 archivaConfigControl.expectAndReturn( archivaConfig.getConfiguration(), config );
327 archivaConfigControl.replay();
329 SearchResults results = search.search( "user", selectedRepos, "org.apache.archiva", null, null );
330 assertNotNull( results );
331 assertEquals( 0, results.getTotalHits() );
333 archivaConfigControl.verify();
336 public void testSearchWithinSearchResults()
339 createIndexForQuickSearch();
341 List<String> selectedRepos = new ArrayList<String>();
342 selectedRepos.add( TEST_REPO_1 );
344 List<String> previousSearchTerms = new ArrayList<String>();
345 previousSearchTerms.add( "archiva-test" );
347 archivaConfigControl.expectAndReturn( archivaConfig.getConfiguration(), config );
349 archivaConfigControl.replay();
351 SearchResults results = search.search( "user", selectedRepos, "1.0", null, previousSearchTerms );
353 archivaConfigControl.verify();
355 assertNotNull( results );
356 assertEquals( 1, results.getTotalHits() );
358 SearchResultHit hit = results.getHits().get( 0 );
359 assertEquals( "org.apache.archiva", hit.getGroupId() );
360 assertEquals( "archiva-test", hit.getArtifactId() );
361 assertEquals( 1, hit.getVersions().size() );
362 assertEquals( "1.0", hit.getVersions().get( 0 ) );
365 // tests for advanced search
367 public void testAdvancedSearch()
370 List<File> files = new ArrayList<File>();
371 files.add( new File( getBasedir(), "/target/test-classes/" + TEST_REPO_2 +
372 "/org/apache/archiva/archiva-search/1.0/archiva-search-1.0.jar" ) );
373 files.add( new File( getBasedir(), "/target/test-classes/" + TEST_REPO_2 +
374 "/org/apache/archiva/archiva-search/1.1/archiva-search-1.1.jar" ) );
375 createIndex( TEST_REPO_2, files );
377 List<String> selectedRepos = new ArrayList<String>();
378 selectedRepos.add( TEST_REPO_2 );
380 SearchFields searchFields = new SearchFields();
381 searchFields.setGroupId( "org.apache.archiva" );
382 searchFields.setVersion( "1.0" );
383 searchFields.setRepositories( selectedRepos );
385 archivaConfigControl.expectAndReturn( archivaConfig.getConfiguration(), config );
387 archivaConfigControl.replay();
389 SearchResults results = search.search( "user", searchFields, null );
391 archivaConfigControl.verify();
393 assertNotNull( results );
394 assertEquals( 1, results.getTotalHits() );
396 SearchResultHit hit = results.getHits().get( 0 );
397 assertEquals( "org.apache.archiva", hit.getGroupId() );
398 assertEquals( "archiva-search", hit.getArtifactId() );
399 assertEquals( "1.0", hit.getVersions().get( 0 ) );
402 public void testAdvancedSearchWithPagination()
405 List<File> files = new ArrayList<File>();
406 files.add( new File( getBasedir(), "/target/test-classes/" + TEST_REPO_1 +
407 "/org/apache/archiva/archiva-search/1.0/archiva-search-1.0.jar" ) );
408 files.add( new File( getBasedir(), "/target/test-classes/" + TEST_REPO_1 +
409 "/org/apache/archiva/archiva-test/1.0/archiva-test-1.0.jar" ) );
410 files.add( new File( getBasedir(), "/target/test-classes/" + TEST_REPO_1 +
411 "/org/apache/archiva/archiva-test/2.0/archiva-test-2.0.jar" ) );
412 files.add( new File( getBasedir(), "/target/test-classes/" + TEST_REPO_1 +
413 "/org/apache/archiva/archiva-webapp/1.0/archiva-webapp-1.0.war" ) );
414 files.add( new File( getBasedir(), "/target/test-classes/" + TEST_REPO_1 +
415 "/com/artifactid-numeric/1.0/artifactid-numeric-1.0.jar" ) );
416 files.add( new File( getBasedir(), "/target/test-classes/" + TEST_REPO_1 +
417 "/com/artifactid-numeric123/1.0/artifactid-numeric123-1.0.jar" ) );
418 files.add( new File( getBasedir(), "/target/test-classes/" + TEST_REPO_1 +
419 "/com/classname-search/1.0/classname-search-1.0.jar" ) );
421 createIndex( TEST_REPO_1, files );
423 List<String> selectedRepos = new ArrayList<String>();
424 selectedRepos.add( TEST_REPO_1 );
426 SearchFields searchFields = new SearchFields();
427 searchFields.setGroupId( "org.apache.archiva" );
428 searchFields.setRepositories( selectedRepos );
432 SearchResultLimits limits = new SearchResultLimits( 0 );
433 limits.setPageSize( 1 );
435 archivaConfigControl.expectAndReturn( archivaConfig.getConfiguration(), config );
437 archivaConfigControl.replay();
439 SearchResults results = search.search( "user", searchFields, limits );
441 archivaConfigControl.verify();
443 assertNotNull( results );
444 assertEquals( 3, results.getTotalHits() );
445 assertEquals( 1, results.getHits().size() );
448 archivaConfigControl.reset();
450 limits = new SearchResultLimits( 1 );
451 limits.setPageSize( 1 );
453 archivaConfigControl.expectAndReturn( archivaConfig.getConfiguration(), config );
455 archivaConfigControl.replay();
457 results = search.search( "user", searchFields, limits );
459 archivaConfigControl.verify();
461 assertNotNull( results );
462 assertEquals( 3, results.getTotalHits() );
463 assertEquals( 1, results.getHits().size() );
466 // MRM-981 - artifactIds with numeric characters aren't found in advanced search
467 public void testAdvancedSearchArtifactIdHasNumericChar()
470 List<File> files = new ArrayList<File>();
471 files.add( new File( getBasedir(), "/target/test-classes/" + TEST_REPO_1 +
472 "/com/artifactid-numeric/1.0/artifactid-numeric-1.0.jar" ) );
473 files.add( new File( getBasedir(), "/target/test-classes/" + TEST_REPO_1 +
474 "/com/artifactid-numeric123/1.0/artifactid-numeric123-1.0.jar" ) );
475 createIndex( TEST_REPO_1, files );
477 List<String> selectedRepos = new ArrayList<String>();
478 selectedRepos.add( TEST_REPO_1 );
480 SearchFields searchFields = new SearchFields();
481 searchFields.setArtifactId( "artifactid-numeric" );
482 searchFields.setRepositories( selectedRepos );
484 archivaConfigControl.expectAndReturn( archivaConfig.getConfiguration(), config, 1 );
486 archivaConfigControl.replay();
488 SearchResults results = search.search( "user", searchFields, null );
490 archivaConfigControl.verify();
492 assertNotNull( results );
493 assertEquals( 2, results.getTotalHits() );
496 public void testAdvancedSearchNoRepositoriesConfigured()
499 SearchFields searchFields = new SearchFields();
500 searchFields.setArtifactId( "archiva" );
501 searchFields.setRepositories( null );
505 search.search( "user", searchFields, null );
506 fail( "A RepositorySearchExcecption should have been thrown." );
508 catch( RepositorySearchException e )
510 assertEquals( "Repositories cannot be null.", e.getMessage() );
514 public void testAdvancedSearchSearchFieldsAreNull()
517 List<String> selectedRepos = new ArrayList<String>();
518 selectedRepos.add( TEST_REPO_1 );
520 SearchFields searchFields = new SearchFields();
521 searchFields.setRepositories( selectedRepos );
525 archivaConfigControl.expectAndReturn( archivaConfig.getConfiguration(), config, 1 );
527 archivaConfigControl.replay();
529 search.search( "user", searchFields, null );
531 archivaConfigControl.verify();
533 fail( "A RepositorySearchExcecption should have been thrown." );
535 catch( RepositorySearchException e )
537 assertEquals( "No search fields set.", e.getMessage() );
541 public void testAdvancedSearchSearchFieldsAreBlank()
544 List<String> selectedRepos = new ArrayList<String>();
545 selectedRepos.add( TEST_REPO_1 );
547 SearchFields searchFields = new SearchFields();
548 searchFields.setGroupId( "" );
549 searchFields.setArtifactId( "" );
550 searchFields.setVersion( "" );
551 searchFields.setPackaging( "" );
552 searchFields.setClassName( "" );
554 searchFields.setRepositories( selectedRepos );
558 archivaConfigControl.expectAndReturn( archivaConfig.getConfiguration(), config, 1 );
560 archivaConfigControl.replay();
562 search.search( "user", searchFields, null );
564 archivaConfigControl.verify();
566 fail( "A RepositorySearchExcecption should have been thrown." );
568 catch( RepositorySearchException e )
570 assertEquals( "No search fields set.", e.getMessage() );
574 public void testAdvancedSearchJarArtifacts()
577 List<File> files = new ArrayList<File>();
578 files.add( new File( getBasedir(), "/target/test-classes/" + TEST_REPO_1 +
579 "/org/apache/archiva/archiva-search/1.0/archiva-search-1.0.jar" ) );
580 files.add( new File( getBasedir(), "/target/test-classes/" + TEST_REPO_1 +
581 "/org/apache/archiva/archiva-test/1.0/archiva-test-1.0.jar" ) );
582 files.add( new File( getBasedir(), "/target/test-classes/" + TEST_REPO_1 +
583 "/org/apache/archiva/archiva-test/2.0/archiva-test-2.0.jar" ) );
584 files.add( new File( getBasedir(), "/target/test-classes/" + TEST_REPO_1 +
585 "/org/apache/archiva/archiva-webapp/1.0/archiva-webapp-1.0.war" ) );
586 files.add( new File( getBasedir(), "/target/test-classes/" + TEST_REPO_1 +
587 "/com/artifactid-numeric/1.0/artifactid-numeric-1.0.jar" ) );
588 files.add( new File( getBasedir(), "/target/test-classes/" + TEST_REPO_1 +
589 "/com/artifactid-numeric123/1.0/artifactid-numeric123-1.0.jar" ) );
590 files.add( new File( getBasedir(), "/target/test-classes/" + TEST_REPO_1 +
591 "/com/classname-search/1.0/classname-search-1.0.jar" ) );
593 createIndex( TEST_REPO_1, files );
595 List<String> selectedRepos = new ArrayList<String>();
596 selectedRepos.add( TEST_REPO_1 );
598 SearchFields searchFields = new SearchFields();
599 searchFields.setPackaging( "jar" );
600 searchFields.setRepositories( selectedRepos );
602 archivaConfigControl.expectAndReturn( archivaConfig.getConfiguration(), config );
604 archivaConfigControl.replay();
606 SearchResults results = search.search( "user", searchFields, null );
608 archivaConfigControl.verify();
610 assertNotNull( results );
611 assertEquals( 5, results.getTotalHits() );
614 public void testAdvancedSearchClassname()
617 List<File> files = new ArrayList<File>();
618 files.add( new File( getBasedir(), "/target/test-classes/" + TEST_REPO_1 +
619 "/org/apache/archiva/archiva-search/1.0/archiva-search-1.0.jar" ) );
620 files.add( new File( getBasedir(), "/target/test-classes/" + TEST_REPO_1 +
621 "/org/apache/archiva/archiva-test/1.0/archiva-test-1.0.jar" ) );
622 files.add( new File( getBasedir(), "/target/test-classes/" + TEST_REPO_1 +
623 "/org/apache/archiva/archiva-test/2.0/archiva-test-2.0.jar" ) );
624 files.add( new File( getBasedir(), "/target/test-classes/" + TEST_REPO_1 +
625 "/org/apache/archiva/archiva-webapp/1.0/archiva-webapp-1.0.war" ) );
626 files.add( new File( getBasedir(), "/target/test-classes/" + TEST_REPO_1 +
627 "/com/artifactid-numeric/1.0/artifactid-numeric-1.0.jar" ) );
628 files.add( new File( getBasedir(), "/target/test-classes/" + TEST_REPO_1 +
629 "/com/artifactid-numeric123/1.0/artifactid-numeric123-1.0.jar" ) );
630 files.add( new File( getBasedir(), "/target/test-classes/" + TEST_REPO_1 +
631 "/com/classname-search/1.0/classname-search-1.0.jar" ) );
633 createIndex( TEST_REPO_1, files );
635 List<String> selectedRepos = new ArrayList<String>();
636 selectedRepos.add( TEST_REPO_1 );
638 SearchFields searchFields = new SearchFields();
639 searchFields.setClassName( "com.classname.search.App" );
640 searchFields.setRepositories( selectedRepos );
642 archivaConfigControl.expectAndReturn( archivaConfig.getConfiguration(), config );
644 archivaConfigControl.replay();
646 SearchResults results = search.search( "user", searchFields, null );
648 archivaConfigControl.verify();
650 assertNotNull( results );
651 assertEquals( 1, results.getTotalHits() );
653 SearchResultHit hit = results.getHits().get( 0 );
654 assertEquals( "com", hit.getGroupId() );
655 assertEquals( "classname-search", hit.getArtifactId() );
656 assertEquals( "1.0", hit.getVersions().get( 0 ) );
659 public void testAdvancedSearchNoIndexFound()
662 List<String> selectedRepos = new ArrayList<String>();
663 selectedRepos.add( TEST_REPO_1 );
665 SearchFields searchFields = new SearchFields();
666 searchFields.setGroupId( "org.apache.archiva" );
667 searchFields.setRepositories( selectedRepos );
669 archivaConfigControl.expectAndReturn( archivaConfig.getConfiguration(), config );
671 archivaConfigControl.replay();
673 SearchResults results = search.search( "user", searchFields, null );
675 archivaConfigControl.verify();
677 assertNotNull( results );assertEquals( 0, results.getTotalHits() );