001/*
002 $Id: Item.java 3677 2010-04-20 12:02:33Z gregory $
003
004 Copyright (C) 2006, 2007 Fredrik Levander, Gregory Vincic, Olle Mansson
005
006 This file is part of Proteios.
007 Available at http://www.proteios.org/
008
009 Proteios is free software; you can redistribute it and/or modify it
010 under the terms of the GNU General Public License as published by
011 the Free Software Foundation; either version 2 of the License, or
012 (at your option) any later version.
013
014 Proteios is distributed in the hope that it will be useful, but
015 WITHOUT ANY WARRANTY; without even the implied warranty of
016 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
017 General Public License for more details.
018
019 You should have received a copy of the GNU General Public License
020 along with this program; if not, write to the Free Software
021 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
022 02111-1307, USA.
023 */
024package org.proteios.core;
025
026import org.proteios.core.data.AcquisitionData;
027import org.proteios.core.data.AnnotationData;
028import org.proteios.core.data.AnnotationSetData;
029import org.proteios.core.data.AnnotationTypeData;
030import org.proteios.core.data.BasicData;
031import org.proteios.core.data.BioMaterialData;
032import org.proteios.core.data.BioMaterialEventData;
033import org.proteios.core.data.BioSourceData;
034import org.proteios.core.data.ClientData;
035import org.proteios.core.data.CreationEventData;
036import org.proteios.core.data.DataProcessingStepData;
037import org.proteios.core.data.DigestParameterData;
038import org.proteios.core.data.DirectoryData;
039import org.proteios.core.data.DiskUsageData;
040import org.proteios.core.data.ExtractData;
041import org.proteios.core.data.FeatureData;
042import org.proteios.core.data.FileData;
043import org.proteios.core.data.FileTypeData;
044import org.proteios.core.data.GelElectrophoresisData;
045import org.proteios.core.data.GelImageAnalysisEventData;
046import org.proteios.core.data.GelScanEventData;
047import org.proteios.core.data.GlobalDefaultSettingData;
048import org.proteios.core.data.GroupData;
049import org.proteios.core.data.HardwareConfigurationData;
050import org.proteios.core.data.HardwareData;
051import org.proteios.core.data.HardwareTypeData;
052import org.proteios.core.data.HitData;
053import org.proteios.core.data.IPGData;
054import org.proteios.core.data.ItemKeyData;
055import org.proteios.core.data.JobData;
056import org.proteios.core.data.LabelData;
057import org.proteios.core.data.LabeledExtractData;
058import org.proteios.core.data.LiquidChromatographyData;
059import org.proteios.core.data.MascotParameterSetStorageData;
060import org.proteios.core.data.MeasuredAreaData;
061import org.proteios.core.data.MessageData;
062import org.proteios.core.data.MimeTypeData;
063import org.proteios.core.data.NewsData;
064import org.proteios.core.data.OMSSAParameterSetStorageData;
065import org.proteios.core.data.ObservedModificationData;
066import org.proteios.core.data.PeakData;
067import org.proteios.core.data.PeakListData;
068import org.proteios.core.data.PeakListSetData;
069import org.proteios.core.data.PeptideData;
070import org.proteios.core.data.PluginConfigurationData;
071import org.proteios.core.data.PluginDefinitionData;
072import org.proteios.core.data.PluginTypeData;
073import org.proteios.core.data.PrecursorData;
074import org.proteios.core.data.ProjectData;
075import org.proteios.core.data.ProjectKeyData;
076import org.proteios.core.data.ProteinData;
077import org.proteios.core.data.ProtocolData;
078import org.proteios.core.data.ProtocolTypeData;
079import org.proteios.core.data.QuotaData;
080import org.proteios.core.data.QuotaTypeData;
081import org.proteios.core.data.RoleData;
082import org.proteios.core.data.RoleKeyData;
083import org.proteios.core.data.SampleData;
084import org.proteios.core.data.SearchDatabaseData;
085import org.proteios.core.data.SearchModificationData;
086import org.proteios.core.data.SearchResultData;
087import org.proteios.core.data.SeparationEventData;
088import org.proteios.core.data.SeparationMethodData;
089import org.proteios.core.data.SessionData;
090import org.proteios.core.data.SettingData;
091import org.proteios.core.data.SoftwareConfigurationData;
092import org.proteios.core.data.SoftwareData;
093import org.proteios.core.data.SoftwareTypeData;
094import org.proteios.core.data.SpectrumSearchData;
095import org.proteios.core.data.StainingEventData;
096import org.proteios.core.data.UpdateEventData;
097import org.proteios.core.data.UserData;
098import org.proteios.core.data.XTandemParameterSetStorageData;
099
100import java.lang.reflect.Constructor;
101import java.lang.reflect.Method;
102import java.util.Collections;
103import java.util.EnumSet;
104import java.util.HashMap;
105import java.util.Map;
106import java.util.Set;
107
108/**
109 * This class defines constants for various items in Proteios.
110 * 
111 * @author Samuel
112 * @version 2.0
113 * @base.modified $Date: 2010-04-20 14:02:33 +0200 (Tue, 20 Apr 2010) $
114 */
115public enum Item
116{
117        /**
118         * Not an item as such. Used for setting system permissions to role keys.
119         * 
120         * @see Install
121         * @see SessionControl#hasSystemPermission(Permission)
122         */
123        SYSTEM(1, "System", null, null, null, null),
124        /**
125         * The item is a {@link User}.
126         */
127        USER(21, "User", "usr", User.class, UserData.class,
128                        DefinedPermissions.basic),
129        /**
130         * The item is a {@link Group}.
131         */
132        GROUP(22, "Group", "grp", Group.class, GroupData.class,
133                        DefinedPermissions.basic),
134        /**
135         * The item is a {@link Role}.
136         */
137        ROLE(23, "Role", "rle", Role.class, RoleData.class,
138                        DefinedPermissions.basic),
139        /**
140         * The item is a {@link Project}.
141         */
142        PROJECT(24, "Project", "prj", Project.class, ProjectData.class,
143                        DefinedPermissions.ownable),
144        /**
145         * The item is an {@link ItemKey}.
146         */
147        ITEMKEY(25, "Item key", "ik", ItemKey.class, ItemKeyData.class, null),
148        /**
149         * The item is a {@link ProjectKey}.
150         */
151        PROJECTKEY(26, "Project key", "pk", ProjectKey.class, ProjectKeyData.class,
152                        null),
153        /**
154         * The item is a {@link RoleKey}.
155         */
156        ROLEKEY(27, "Role key", "rk", RoleKey.class, RoleKeyData.class, null),
157        /**
158         * The item is an {@link Client}.
159         */
160        CLIENT(41, "Client", "cli", Client.class, ClientData.class,
161                        DefinedPermissions.shareable),
162        /**
163         * The item is an {@link Session}.
164         */
165        SESSION(43, "Session", "ses", Session.class, SessionData.class,
166                        DefinedPermissions.read),
167        /**
168         * The item is an {@link Setting}.
169         */
170        SETTING(44, "Setting", "set", Setting.class, SettingData.class,
171                        DefinedPermissions.basic),
172        /**
173         * The item is an {@link GlobalDefaultSetting}.
174         */
175        GLOBALDEFAULTSETTING(45, "Global default setting", "gds",
176                        GlobalDefaultSetting.class, GlobalDefaultSettingData.class,
177                        DefinedPermissions.basic),
178        /**
179         * The item is a {@link Quota}.
180         */
181        QUOTA(61, "Quota", "qta", Quota.class, QuotaData.class,
182                        DefinedPermissions.basic),
183        /**
184         * The item is a {@link QuotaType}.
185         */
186        QUOTATYPE(62, "Quota type", "qtp", QuotaType.class, QuotaTypeData.class,
187                        DefinedPermissions.write),
188        /**
189         * The item is a {@link DiskUsage}.
190         */
191        DISKUSAGE(63, "Disk usage", "du", DiskUsage.class, DiskUsageData.class,
192                        DefinedPermissions.read),
193        /**
194         * The item is a {@link File}.
195         */
196        FILE(81, "File", "fle", File.class, FileData.class,
197                        DefinedPermissions.shareable),
198        /**
199         * The item is a {@link FileType}.
200         */
201        FILETYPE(82, "File type", "ftp", FileType.class, FileTypeData.class,
202                        DefinedPermissions.write),
203        /**
204         * The item is a {@link Directory}.
205         */
206        DIRECTORY(83, "Directory", "dir", Directory.class, DirectoryData.class,
207                        DefinedPermissions.shareable),
208        /**
209         * The item is a {@link MimeType}.
210         */
211        MIMETYPE(84, "Mime type", "mtp", MimeType.class, MimeTypeData.class,
212                        DefinedPermissions.basic),
213        /**
214         * The item is a {@link Protocol}.
215         */
216        PROTOCOL(101, "Protocol", "prl", Protocol.class, ProtocolData.class,
217                        DefinedPermissions.shareable),
218        /**
219         * The item is a {@link ProtocolType}.
220         */
221        PROTOCOLTYPE(102, "Protocol type", "ptp", ProtocolType.class,
222                        ProtocolTypeData.class, DefinedPermissions.basic),
223        /**
224         * The item is a {@link Hardware}.
225         */
226        HARDWARE(121, "Hardware", "hw", Hardware.class, HardwareData.class,
227                        DefinedPermissions.shareable),
228        /**
229         * The item is a {@link HardwareType}.
230         */
231        HARDWARETYPE(122, "Hardware type", "htp", HardwareType.class,
232                        HardwareTypeData.class, DefinedPermissions.write),
233        /**
234         * The item is a {@link Software}.
235         */
236        SOFTWARE(123, "Software", "sw", Software.class, SoftwareData.class,
237                        DefinedPermissions.shareable),
238        /**
239         * The item is a {@link SoftwareType}.
240         */
241        SOFTWARETYPE(124, "Software type", "stp", SoftwareType.class,
242                        SoftwareTypeData.class, DefinedPermissions.write),
243        /**
244         * The item is a {@link News}.
245         */
246        NEWS(141, "News", "nws", News.class, NewsData.class,
247                        DefinedPermissions.basic),
248        /**
249         * The item is a {@link Message}.
250         */
251        MESSAGE(142, "Message", "msg", Message.class, MessageData.class,
252                        DefinedPermissions.basic),
253        /**
254         * The item is an {@link AnnotationSet}.
255         */
256        ANNOTATIONSET(181, "Annotation set", "ans", AnnotationSet.class,
257                        AnnotationSetData.class, DefinedPermissions.basic),
258        /**
259         * The item is an {@link Annotation}.
260         */
261        ANNOTATION(182, "Annotation", "ann", Annotation.class,
262                        AnnotationData.class, DefinedPermissions.basic),
263        /**
264         * The item is an {@link AnnotationType}.
265         */
266        ANNOTATIONTYPE(183, "Annotation type", "atp", AnnotationType.class,
267                        AnnotationTypeData.class, DefinedPermissions.shareable),
268        /**
269         * The item is a {@link BioSource}.
270         */
271        BIOSOURCE(201, "Biosource", "bs", BioSource.class, BioSourceData.class,
272                        DefinedPermissions.shareable),
273        /**
274         * The item is a {@link Sample}.
275         */
276        SAMPLE(202, "Sample", "smp", Sample.class, SampleData.class,
277                        DefinedPermissions.shareable),
278        /**
279         * The item is an {@link Extract}.
280         */
281        EXTRACT(203, "Extract", "xtr", Extract.class, ExtractData.class,
282                        DefinedPermissions.shareable),
283        /**
284         * The item is a {@link LabeledExtract}.
285         */
286        LABELEDEXTRACT(204, "Labeled extract", "lbe", LabeledExtract.class,
287                        LabeledExtractData.class, DefinedPermissions.shareable),
288        /**
289         * The item is a {@link BioMaterialEvent}.
290         */
291        BIOMATERIALEVENT(205, "Biomaterial event", "bme", BioMaterialEvent.class,
292                        BioMaterialEventData.class, null),
293        /**
294         * The item is a {@link Label}.
295         */
296        LABEL(206, "Label", "lbl", Label.class, LabelData.class,
297                        DefinedPermissions.shareable),
298        /**
299         * The item is a {@link PluginType}
300         */
301        PLUGINTYPE(281, "Plugin type", "plt", PluginType.class,
302                        PluginTypeData.class, DefinedPermissions.basic),
303        /**
304         * The item is a {@link PluginDefinition}
305         */
306        PLUGINDEFINITION(282, "Plugin definition", "pld", PluginDefinition.class,
307                        PluginDefinitionData.class, DefinedPermissions.shareable),
308        /**
309         * The item is a {@link PluginConfiguration}
310         */
311        PLUGINCONFIGURATION(283, "Plugin configuration", "plc",
312                        PluginConfiguration.class, PluginConfigurationData.class,
313                        DefinedPermissions.shareable),
314        /**
315         * The item is a {@link Job}
316         */
317        JOB(284, "Job", "job", Job.class, JobData.class, DefinedPermissions.ownable),
318        /**
319         * The item is a {@link HardwareConfiguration}
320         */
321        HARDWARECONFIGURATION(401, "HardwareConfiguration", "hwc",
322                        HardwareConfiguration.class, HardwareConfigurationData.class,
323                        DefinedPermissions.shareable),
324        /**
325         * The item is a {@link SoftwareConfiguration}
326         */
327        SOFTWARECONFIGURATION(402, "SoftwareConfiguration", "swc",
328                        SoftwareConfiguration.class, SoftwareConfigurationData.class,
329                        DefinedPermissions.shareable),
330        /**
331         * Not an item as such. Used as a convenient way to set an offset for the
332         * index value of Proteios constants.
333         */
334        PROTEIOS_OFFSET(500, "Proteios_offset", null, null, null, null),
335        /**
336         * The item is a {@link PeakListSet}
337         */
338        PROTEIOS_PEAKLISTSET(PROTEIOS_OFFSET.value + 1, "PeakListSet", "pls",
339                        PeakListSet.class, PeakListSetData.class,
340                        DefinedPermissions.shareable),
341        /**
342         * The item is a {@link PeakList}
343         */
344        PROTEIOS_PEAKLIST(PROTEIOS_OFFSET.value + 2, "PeakList", "pl",
345                        PeakList.class, PeakListData.class, DefinedPermissions.shareable),
346        /**
347         * The item is a {@link DataProcessingStep}
348         */
349        PROTEIOS_DATAPROCESSINGSTEP(PROTEIOS_OFFSET.value + 3,
350                        "DataProcessingStep", "dps", DataProcessingStep.class,
351                        DataProcessingStepData.class, DefinedPermissions.shareable),
352        /**
353         * The item is a {@link Precursor}
354         */
355        PROTEIOS_PRECURSOR(PROTEIOS_OFFSET.value + 4, "Precursor", "pc",
356                        Precursor.class, PrecursorData.class, DefinedPermissions.shareable),
357        /**
358         * The item is a {@link Peak}
359         */
360        PROTEIOS_PEAK(PROTEIOS_OFFSET.value + 5, "Peak", "pk", Peak.class,
361                        PeakData.class, DefinedPermissions.basic),
362        /**
363         * The item is an {@link Acquisition}
364         */
365        PROTEIOS_ACQUISITION(PROTEIOS_OFFSET.value + 6, "Acquisition", "ac",
366                        Acquisition.class, AcquisitionData.class,
367                        DefinedPermissions.shareable),
368        /**
369         * The item is an {@link SpectrumSearch}
370         */
371        PROTEIOS_SPECTRUMSEARCH(PROTEIOS_OFFSET.value + 7, "SpectrumSearch", "sps",
372                        SpectrumSearch.class, SpectrumSearchData.class,
373                        DefinedPermissions.shareable),
374        /**
375         * The item is an {@link DigestParameter}
376         */
377        PROTEIOS_DIGESTPARAMETER(PROTEIOS_OFFSET.value + 8, "DigestParameter",
378                        "dip", DigestParameter.class, DigestParameterData.class,
379                        DefinedPermissions.shareable),
380        /**
381         * The item is an {@link SearchDatabase}
382         */
383        PROTEIOS_SEARCHDATABASE(PROTEIOS_OFFSET.value + 9, "SearchDatabase", "sdb",
384                        SearchDatabase.class, SearchDatabaseData.class,
385                        DefinedPermissions.shareable),
386        /**
387         * The item is a {@link SearchResult}
388         */
389        PROTEIOS_SEARCHRESULT(PROTEIOS_OFFSET.value + 10, "SearchResult", "ser",
390                        SearchResult.class, SearchResultData.class,
391                        DefinedPermissions.shareable),
392        /**
393         * The item is a {@link Protein}
394         */
395        PROTEIOS_PROTEIN(PROTEIOS_OFFSET.value + 11, "Protein", "pro",
396                        Protein.class, ProteinData.class, DefinedPermissions.shareable),
397        /**
398         * The item is a {@link Peptide}
399         */
400        PROTEIOS_PEPTIDE(PROTEIOS_OFFSET.value + 12, "Peptide", "pep",
401                        Peptide.class, PeptideData.class, DefinedPermissions.shareable),
402        /**
403         * The item is a {@link Hit}
404         */
405        PROTEIOS_HIT(PROTEIOS_OFFSET.value + 14, "Hit", "hit", Hit.class,
406                        HitData.class, DefinedPermissions.basic),
407        /**
408         * The item is a {@link MeasuredArea}
409         */
410        PROTEIOS_MEASUREDAREA(PROTEIOS_OFFSET.value + 15, "MeasuredArea", "ma",
411                        MeasuredArea.class, MeasuredAreaData.class,
412                        DefinedPermissions.shareable),
413        /**
414         * The item is a {@link GelElectrophoresis}
415         */
416        PROTEIOS_GELELECTROPHORESIS(PROTEIOS_OFFSET.value + 16,
417                        "GelElectrophoresis", "geps", GelElectrophoresis.class,
418                        GelElectrophoresisData.class, DefinedPermissions.shareable),
419        /**
420         * The item is an {@link IPG}
421         */
422        PROTEIOS_IPG(PROTEIOS_OFFSET.value + 17, "IPG", "ipg", IPG.class,
423                        IPGData.class, DefinedPermissions.shareable),
424        /**
425         * The item is a {@link SeparationMethod}
426         */
427        PROTEIOS_SEPARATIONMETHOD(PROTEIOS_OFFSET.value + 18, "SeparationMethod",
428                        "sm", SeparationMethod.class, SeparationMethodData.class,
429                        DefinedPermissions.shareable),
430        /**
431         * The item is a {@link GelImageAnalysisEvent}
432         */
433        PROTEIOS_GELIMAGEANALYSISEVENT(PROTEIOS_OFFSET.value + 19,
434                        "GelImageAnalysisEvent", "giae", GelImageAnalysisEvent.class,
435                        GelImageAnalysisEventData.class, DefinedPermissions.shareable),
436        /**
437         * The item is a {@link GelScanEvent}
438         */
439        PROTEIOS_GELSCANEVENT(PROTEIOS_OFFSET.value + 20, "GelScanEvent", "gse",
440                        GelScanEvent.class, GelScanEventData.class,
441                        DefinedPermissions.shareable),
442        /**
443         * The item is a {@link SeparationEvent}
444         */
445        PROTEIOS_SEPARATIONEVENT(PROTEIOS_OFFSET.value + 21, "SeparationEvent",
446                        "se", SeparationEvent.class, SeparationEventData.class,
447                        DefinedPermissions.shareable),
448        /**
449         * The item is a {@link StainingEvent}
450         */
451        PROTEIOS_STAININGEVENT(PROTEIOS_OFFSET.value + 22, "StainingEvent", "se",
452                        StainingEvent.class, StainingEventData.class,
453                        DefinedPermissions.shareable),
454        /**
455         * The item is a {@link ObservedModification}
456         */
457        PROTEIOS_OBSERVEDMODIFICATION(PROTEIOS_OFFSET.value + 23,
458                        "ObservedModification", "om", ObservedModification.class,
459                        ObservedModificationData.class, DefinedPermissions.shareable),
460        /**
461         * The item is a {@link SearchModification}
462         */
463        PROTEIOS_SEARCHMODIFICATION(PROTEIOS_OFFSET.value + 24,
464                        "SearchModification", "sm", SearchModification.class,
465                        SearchModificationData.class, DefinedPermissions.shareable),
466        /**
467         * The item is a {@link CreationEvent}
468         */
469        PROTEIOS_CREATIONEVENT(PROTEIOS_OFFSET.value + 25, "CreationEvent", "cev",
470                        CreationEvent.class, CreationEventData.class,
471                        DefinedPermissions.basic),
472        /**
473         * The item is a {@link BioMaterial}. Was introduced when trying to display
474         * any biomaterial by clicking on it.
475         */
476        PROTEIOS_BIOMATERIAL(PROTEIOS_OFFSET.value + 26, "BioMaterial", "bml",
477                        BioMaterial.class, BioMaterialData.class, DefinedPermissions.basic),
478        /**
479         * The item is an {@link UpdateEvent}
480         */
481        PROTEIOS_UPDATEEVENT(PROTEIOS_OFFSET.value + 27, "UpdateEvent", "ue",
482                        UpdateEvent.class, UpdateEventData.class,
483                        DefinedPermissions.shareable),
484        /**
485         * The item is a {@link LiquidChromatography}
486         */
487        PROTEIOS_LIQUIDCHROMATOGRAPHY(PROTEIOS_OFFSET.value + 28,
488                        "LiquidChromatography", "lc", LiquidChromatography.class,
489                        LiquidChromatographyData.class, DefinedPermissions.shareable),
490        /**
491         * The item is an {@link XTandemParameterSetStorage}
492         */
493        PROTEIOS_XTANDEMPARAMETERSETSTORAGE(PROTEIOS_OFFSET.value + 29,
494                        "XTandemParameterSetStorage", "xtpss", XTandemParameterSetStorage.class,
495                        XTandemParameterSetStorageData.class, DefinedPermissions.shareable),
496        /**
497         * The item is an {@link OMSSAParameterSetStorage}
498         */
499        PROTEIOS_OMSSAPARAMETERSETSTORAGE(PROTEIOS_OFFSET.value + 30,
500                        "OMSSAParameterSetStorage", "omssapss", OMSSAParameterSetStorage.class,
501                        OMSSAParameterSetStorageData.class, DefinedPermissions.shareable),
502        /**
503         * The item is a {@link MascotParameterSetStorage}
504         */
505        PROTEIOS_MASCOTPARAMETERSETSTORAGE(PROTEIOS_OFFSET.value + 31,
506                        "MascotParameterSetStorage", "mascotpss", MascotParameterSetStorage.class,
507                        MascotParameterSetStorageData.class, DefinedPermissions.shareable),
508        /**
509         * The item is a {@link MascotParameterSetStorage}
510         */
511        PROTEIOS_FEATURE(PROTEIOS_OFFSET.value + 32,
512                        "Feature", "feat", Feature.class,
513                        FeatureData.class, DefinedPermissions.basic);
514        /**
515         * The largest id value used to verify that there are no two items with the
516         * same id
517         */
518        static int MAX_VALUE = 0;
519        /**
520         * Maps the id value with the enumerated value, used to verify that only one
521         * id value is mapped to one enumerated value
522         */
523        private static final Map<Integer, Item> valueMapping = new HashMap<Integer, Item>();
524        /**
525         * Maps the enumeration with an alias, used to verify that there is only one
526         * alias for each item
527         */
528        private static final Map<String, Item> aliasMapping = new HashMap<String, Item>();
529        /**
530         * Maps a wrapper class with the enumerated value
531         */
532        @SuppressWarnings("unchecked")
533        private static final Map<Class<? extends BasicItem>, Item> itemClassMapping = new HashMap<Class<? extends BasicItem>, Item>();
534        /**
535         * Maps a data class with the enumerated value
536         */
537        private static final Map<Class<? extends BasicData>, Item> dataClassMapping = new HashMap<Class<? extends BasicData>, Item>();
538        /*
539         * Verify that all enumerated values have one wrapper class, one data class,
540         * a unique alias and a unique id
541         */
542        static
543        {
544                for (Item item : Item.values())
545                {
546                        int value = item.getValue();
547                        if (MAX_VALUE < value)
548                                MAX_VALUE = value;
549                        Item i = valueMapping.put(value, item);
550                        assert i == null : "Another item with the value " + value + " already exists: " + i;
551                        i = aliasMapping.put(item.getAlias(), item);
552                        assert i == null : "Another item with the alias " + item.getAlias() + " already exists: " + i;
553                        if (item.getItemClass() != null)
554                        {
555                                i = itemClassMapping.put(item.getItemClass(), item);
556                                assert i == null : "Another item for class " + item
557                                        .getItemClass() + " already exists: " + i;
558                        }
559                        if (item.getDataClass() != null)
560                        {
561                                i = dataClassMapping.put(item.getDataClass(), item);
562                                assert i == null : "Another item for class " + item
563                                        .getDataClass() + " already exists: " + i;
564                        }
565                }
566        }
567        private final int value;
568        private final String displayValue;
569        private final String alias;
570        @SuppressWarnings("unchecked")
571        private final Class<? extends BasicItem> itemClass;
572        private final Class<? extends BasicData> dataClass;
573        private final Set<Permission> definedPermissions;
574        private final Method getById;
575        @SuppressWarnings("unchecked")
576        private final Constructor<? extends BasicItem> constructor;
577
578
579        @SuppressWarnings("unchecked")
580        private Item(int value, String displayValue, String alias,
581                        Class<? extends BasicItem> itemClass,
582                        Class<? extends BasicData> dataClass,
583                        Set<Permission> definedPermissions)
584        {
585                this.value = value;
586                this.displayValue = displayValue;
587                this.alias = alias;
588                this.itemClass = itemClass;
589                this.dataClass = dataClass;
590                this.definedPermissions = definedPermissions;
591                Method tempGetById = null;
592                Constructor<? extends BasicItem> tempConstructor = null;
593                if (itemClass != null)
594                {
595                        try
596                        {
597                                tempGetById = itemClass.getDeclaredMethod("getById",
598                                        DbControl.class, int.class);
599                        }
600                        catch (NoSuchMethodException ex)
601                        {}
602                        try
603                        {
604                                tempConstructor = itemClass.getDeclaredConstructor(dataClass);
605                        }
606                        catch (NoSuchMethodException ex)
607                        {}
608                }
609                getById = tempGetById;
610                constructor = tempConstructor;
611        }
612
613
614        @Override
615        public String toString()
616        {
617                return displayValue;
618        }
619
620
621        /**
622         * Get the integer value that is used when storing an item to the database.
623         */
624        public int getValue()
625        {
626                return value;
627        }
628
629
630        /**
631         * Get the alias for this item, which is used in queries,
632         * 
633         * @see org.proteios.core.query.Query#getRootAlias()
634         */
635        public String getAlias()
636        {
637                return alias;
638        }
639
640
641        /**
642         * Get the class object that is used to handle items of this type.
643         */
644        @SuppressWarnings("unchecked")
645        public Class<? extends BasicItem> getItemClass()
646        {
647                return itemClass;
648        }
649
650
651        /**
652         * Get the data object that is used to store information in the database for
653         * items of this type.
654         */
655        public Class<? extends BasicData> getDataClass()
656        {
657                return dataClass;
658        }
659
660
661        /**
662         * Get the permissions which are meaningful to assign to an item if this
663         * type. This is not used internally by the core, but is can be used by
664         * client applications to dynamically display a proper input form while
665         * assigning permissions.
666         * 
667         * @return A <code>Set</code> containing the permissions
668         */
669        public Set<Permission> getDefinedPermissions()
670        {
671                return definedPermissions;
672        }
673
674
675        /**
676         * Get the item of the type represented by this enumeration constant with
677         * the specified id. Ie. <code>Item.SAMPLE.getById()</code> is the same as
678         * <code>Sample.getById</code>.
679         * 
680         * @param dc The <code>DbControl</code> object used for database access
681         *        and permission checking
682         * @param id The id of the item
683         * @return An item of the type represented by this enumeration constant
684         * @throws ItemNotFoundException If an item with the specified id isn't
685         *         found
686         * @throws PermissionDeniedException If the logged in user hasn't read
687         *         permission for the item
688         * @throws BaseException If there is another error
689         */
690        @SuppressWarnings("unchecked")
691        public BasicItem getById(DbControl dc, int id)
692                        throws ItemNotFoundException, PermissionDeniedException,
693                        BaseException
694        {
695                if (getById == null)
696                {
697                        throw new ItemNotFoundException(itemClass + "[id=" + id + "]");
698                }
699                try
700                {
701                        return (BasicItem) getById.invoke(null, dc, id);
702                }
703                catch (Throwable ex)
704                {
705                        Throwable cause = ex.getCause();
706                        if (cause instanceof BaseException)
707                        {
708                                throw (BaseException) cause;
709                        }
710                        else if (cause != null)
711                        {
712                                throw new BaseException(cause);
713                        }
714                        else
715                        {
716                                throw new BaseException(ex);
717                        }
718                }
719        }
720
721
722        /**
723         * Get the default constructor for new objects of this type. The default
724         * constructor is a constructor that takes a <code>BasicData</code> object
725         * as the only parameter. For example <code>Sample(SampleData data)</code>.
726         * 
727         * @return The constructor, or null if no such constructor exists
728         * @see DbControl#getItem(Class, BasicData, Object[])
729         */
730        @SuppressWarnings("unchecked")
731        Constructor<? extends BasicItem> getConstructor()
732        {
733                return constructor;
734        }
735
736
737        /**
738         * Get the <code>Item</code> object when you know the integer code.
739         */
740        public static Item fromValue(int value)
741        {
742                Item item = valueMapping.get(value);
743                assert item != null : "item == null for value " + value;
744                return item;
745        }
746
747
748        /**
749         * Get the <code>Item</code> object when you know the item class.
750         */
751        @SuppressWarnings("unchecked")
752        public static Item fromItemClass(Class<? extends BasicItem> itemClass)
753        {
754                Item item = itemClassMapping.get(itemClass);
755                assert item != null : "item == null for itemClass " + itemClass;
756                return item;
757        }
758
759
760        /**
761         * Get the <code>Item</code> object when you know the data class.
762         */
763        public static Item fromDataClass(Class<? extends BasicData> dataClass)
764        {
765                Item item = dataClassMapping.get(dataClass);
766                assert item != null : "item == null for dataClass " + dataClass;
767                return item;
768        }
769
770
771        /**
772         * Get the <code>Item</code> object when you know either the item or data
773         * class.
774         * 
775         * @return The Item object, or null if no matching item is found
776         */
777        @SuppressWarnings(
778                {
779                        "unchecked"
780                })
781        public static Item fromClass(Class<?> anyClass)
782        {
783                Item item = null;
784                if (BasicItem.class.isAssignableFrom(anyClass))
785                {
786                        item = fromItemClass((Class<BasicItem>) anyClass);
787                }
788                else if (BasicData.class.isAssignableFrom(anyClass))
789                {
790                        item = fromDataClass((Class<BasicData>) anyClass);
791                }
792                return item;
793        }
794
795
796        /**
797         * Get the <code>Item</code> object when you have a data layer object.
798         * This method takes Hibernate proxies into account.
799         */
800        @SuppressWarnings(
801                {
802                        "unchecked"
803                })
804        public static Item fromDataObject(BasicData data)
805        {
806                Class<? extends BasicData> dataClass = data.getClass();
807                if (data instanceof org.hibernate.proxy.HibernateProxy)
808                {
809                        dataClass = org.hibernate.proxy.HibernateProxyHelper
810                                .getClassWithoutInitializingProxy(data);
811                }
812                return fromDataClass(dataClass);
813        }
814
815        /**
816         * Helper class to make it easier to set up the defined permissions.
817         * 
818         * @see #getDefinedPermissions()
819         */
820        private static class DefinedPermissions
821        {
822                private static final Set<Permission> read = Collections
823                        .unmodifiableSet(EnumSet.of(Permission.READ));
824                private static final Set<Permission> write = Collections
825                        .unmodifiableSet(EnumSet.of(Permission.READ, Permission.USE,
826                                Permission.WRITE));
827                private static final Set<Permission> basic = Collections
828                        .unmodifiableSet(EnumSet.of(Permission.CREATE, Permission.READ,
829                                Permission.USE, Permission.WRITE, Permission.DELETE));
830                private static final Set<Permission> ownable = Collections
831                        .unmodifiableSet(EnumSet.of(Permission.CREATE, Permission.READ,
832                                Permission.USE, Permission.WRITE, Permission.DELETE,
833                                Permission.SET_OWNER));
834                private static final Set<Permission> shareable = Collections
835                        .unmodifiableSet(EnumSet.of(Permission.CREATE, Permission.READ,
836                                Permission.USE, Permission.WRITE, Permission.DELETE,
837                                Permission.SET_OWNER, Permission.SET_PERMISSION));
838        }
839}