1 # This file is part of NIT ( http://www.nitlanguage.org ).
3 # Licensed under the Apache License, Version 2.0 (the "License");
4 # you may not use this file except in compliance with the License.
5 # You may obtain a copy of the License at
7 # http://www.apache.org/licenses/LICENSE-2.0
9 # Unless required by applicable law or agreed to in writing, software
10 # distributed under the License is distributed on an "AS IS" BASIS,
11 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 # See the License for the specific language governing permissions and
13 # limitations under the License.
15 # Commands to retrieve Catalog related data
16 module commands_catalog
20 # A DocCommand based on a Catalog
21 abstract class CmdCatalog
24 autoinit
(model
, catalog
, filter
)
30 # A CmdSearch command using a Catalog
31 class CmdCatalogSearch
35 autoinit
(model
, catalog
, filter
, query
, limit
, page
, count
, max
)
37 redef fun init_results
do
38 if results
!= null then return new CmdSuccess
41 if not res
isa CmdSuccess then return res
43 var query
= self.query
44 if query
== null then return new ErrorNoQuery
47 var filter
= self.filter
48 var index
= model
.index
50 # lookup by name prefix
51 var matches
= index
.find_by_name_prefix
(query
, filter
).uniq
.
52 sort
(lname_sorter
, name_sorter
, kind_sorter
)
53 matches
= matches
.rerank
.sort
(vis_sorter
, score_sorter
)
56 var malus
= matches
.length
57 if catalog
.tag2proj
.has_key
(query
) then
58 for mpackage
in catalog
.tag2proj
[query
] do
59 if filter
!= null and not filter
.accept_mentity
(mpackage
) then continue
60 matches
.add
new IndexMatch(mpackage
, malus
)
63 matches
= matches
.uniq
.rerank
.sort
(vis_sorter
, score_sorter
)
66 # lookup by full_name prefix
67 malus
= matches
.length
68 var full_matches
= new IndexMatches
69 for match
in index
.find_by_full_name_prefix
(query
, filter
).
70 sort
(lfname_sorter
, fname_sorter
) do
72 full_matches
.add match
74 matches
= matches
.uniq
76 # lookup by similarity
77 malus
= matches
.length
78 var sim_matches
= new IndexMatches
79 for match
in index
.find_by_similarity
(query
, filter
).sort
(score_sorter
, kind_sorter
, lname_sorter
, name_sorter
) do
80 if match
.score
> query
.length
then break
84 matches
.add_all sim_matches
85 matches
= matches
.uniq
86 results
= matches
.rerank
.sort
(vis_sorter
, score_sorter
).mentities
90 private var score_sorter
= new ScoreComparator
91 private var vis_sorter
= new VisibilityComparator
92 private var name_sorter
= new NameComparator
93 private var lname_sorter
= new NameLengthComparator
94 private var fname_sorter
= new FullNameComparator
95 private var lfname_sorter
= new FullNameLengthComparator
96 private var kind_sorter
= new MEntityComparator
99 # Retrieve the catalog metadata for a MPackage
103 # MPackage metadata retrieved
104 var metadata
: nullable MPackageMetadata = null is optional
, writable
106 redef fun init_command
do
107 if metadata
!= null then return new CmdSuccess
110 if not res
isa CmdSuccess then return res
111 var mentity
= self.mentity
.as(not null)
113 if mentity
isa MPackage then
114 metadata
= mentity
.metadata
116 return new WarningNoMetadata(mentity
)
122 # No metadata for `mentity`
123 class WarningNoMetadata
129 redef fun to_s
do return "No metadata for `{mentity.full_name}`"
132 # Retrieve the packages in the catalog
133 class CmdCatalogPackages
137 autoinit
(model
, catalog
, filter
, limit
, page
, count
, max
)
139 redef var sorter
= new CatalogScoreSorter(catalog
) is lazy
141 redef fun init_results
do
142 if results
!= null then return new CmdSuccess
145 if not res
isa CmdSuccess then return res
147 results
= catalog
.mpackages
.values
.to_a
152 # Retrieve the catalog stats
153 class CmdCatalogStats
156 # Retrieved catalog statistics
157 var stats
: nullable CatalogStats = null is optional
, writable
159 redef fun init_command
do
161 self.stats
= catalog
.catalog_stats
162 return new CmdSuccess
166 # Retrieve the catalog tags list
170 # Sorter to sort tags alphabetically
171 var tags_sorter
= new CatalogTagsSorter is optional
, writable
173 # Count of packages by tag
174 var packages_count_by_tags
: nullable ArrayMap[String, Int] = null is optional
, writable
176 redef fun init_command
do
178 var tags_to_projects
= new ArrayMap[String, Int]
179 var tags
= catalog
.tag2proj
.keys
.to_a
180 tags_sorter
.sort
(tags
)
182 if not catalog
.tag2proj
.has_key
(tag
) then continue
183 tags_to_projects
[tag
] = catalog
.tag2proj
[tag
].length
185 packages_count_by_tags
= tags_to_projects
186 return new CmdSuccess
190 # Retrieve the packages for a tag
192 super CmdCatalogPackages
194 autoinit
(model
, catalog
, filter
, tag
, limit
, page
, count
, max
)
196 # The tag to retrieve
197 var tag
: nullable String = null is optional
, writable
199 redef fun init_command
do
201 if tag
== null then return new ErrorNoTag
203 if not catalog
.tag2proj
.has_key
(tag
) then return new ErrorTagNotFound(tag
)
207 redef fun init_results
do
208 if results
!= null then return new CmdSuccess
211 if not res
isa CmdSuccess then return res
213 results
= catalog
.tag2proj
[tag
].to_a
218 # No tag name provided
222 redef fun to_s
do return "No tag name provided"
225 # No tag with this name in the catalog
226 class ErrorTagNotFound
229 # The tag that was not found
232 redef fun to_s
do return "No tag found for `{tag}`"
235 # Retrieve a person from the catalog
236 class CmdCatalogPerson
241 # You can also pass a `person_name`.
242 var person
: nullable Person = null is optional
, writable
244 # Name of the person to retrieve
246 # You can also pass a `person` instance.
247 var person_name
: nullable String = null is optional
, writable
249 # Initialize the `person` result
250 fun init_person
: CmdMessage do
251 var person
= self.person
252 if person
!= null then
253 person_name
= person
.name
254 return new CmdSuccess
257 var name
= self.person_name
258 if name
== null then return new ErrorNoPerson
259 if not catalog
.name2person
.has_key
(name
) then return new ErrorPersonNotFound(name
)
260 self.person
= catalog
.name2person
[name
]
261 return new CmdSuccess
264 redef fun init_command
do
270 # No person instance or name provided
274 redef fun to_s
do return "No person provided"
277 # No person found with this name
278 class ErrorPersonNotFound
281 # Name of the person that was not found
284 redef fun to_s
do return "No person found for `{name}`"
287 # Retrieve the packages maintained by a person
288 class CmdCatalogMaintaining
289 super CmdCatalogPerson
290 super CmdCatalogPackages
292 autoinit
(model
, catalog
, filter
, person
, person_name
, limit
, page
, count
, max
)
294 redef fun init_command
do return super
296 redef fun init_results
do
297 if results
!= null then return new CmdSuccess
299 if not res
isa CmdSuccess then return res
300 var person
= self.person
.as(not null)
302 if not catalog
.maint2proj
.has_key
(person
) then return res
303 results
= catalog
.maint2proj
[person
]
308 # Retrieve the packages contributed by a person
309 class CmdCatalogContributing
310 super CmdCatalogPerson
311 super CmdCatalogPackages
313 autoinit
(model
, catalog
, filter
, person
, person_name
, limit
, page
, count
, max
)
315 # Include maintained packages?
317 # Default is `false`.
318 var maintaining
= false is optional
, writable
320 # FIXME linearization
321 redef fun init_command
do return super
323 redef fun init_results
do
324 if results
!= null then return new CmdSuccess
327 if not res
isa CmdSuccess then return res
328 var person
= self.person
.as(not null)
330 if not catalog
.contrib2proj
.has_key
(person
) then return res
332 var maint2proj
= null
333 if catalog
.maint2proj
.has_key
(person
) then
334 maint2proj
= catalog
.maint2proj
[person
]
337 var results
= new Array[MPackage]
338 for mpackage
in catalog
.contrib2proj
[person
] do
339 if not maintaining
and maint2proj
!= null and maint2proj
.has
(mpackage
) then continue
342 self.results
= results