1 // -*- Mode: Java; indent-tabs-mode: t; tab-width: 4 -*-
2 // ---------------------------------------------------------------------------
4 // Copyright (C) Stephanie Gawroriski <xer@multiphasicapps.net>
5 // ---------------------------------------------------------------------------
6 // SquirrelJME is under the Mozilla Public License Version 2.0.
7 // See license.mkd for licensing and copyright information.
8 // ---------------------------------------------------------------------------
10 package cc
.squirreljme
.jvm
.suite
;
12 import cc
.squirreljme
.jvm
.manifest
.JavaManifestAttributes
;
13 import cc
.squirreljme
.runtime
.cldc
.util
.StringUtils
;
14 import cc
.squirreljme
.runtime
.cldc
.util
.UnmodifiableIterator
;
15 import java
.lang
.ref
.Reference
;
16 import java
.lang
.ref
.WeakReference
;
17 import java
.util
.Arrays
;
18 import java
.util
.Collection
;
19 import java
.util
.Iterator
;
20 import java
.util
.LinkedHashSet
;
24 * This contains the information which specifies all of the dependencies which
25 * and application depends on.
29 public final class DependencyInfo
30 implements Iterable
<MarkedDependency
>
32 /** The dependencies. */
33 private final Set
<MarkedDependency
> _depends
;
35 /** String representation. */
36 private Reference
<String
> _string
;
39 * Initializes the dependency information.
41 * @param __deps The dependencies to depend on.
44 public DependencyInfo(MarkedDependency
... __deps
)
46 this(Arrays
.<MarkedDependency
>asList((__deps
== null ?
47 new MarkedDependency
[0] : __deps
)));
51 * Initializes the dependency information.
53 * @param __deps The dependencies to use.
54 * @throws NullPointerException On null arguments.
57 public DependencyInfo(Collection
<MarkedDependency
> __deps
)
58 throws NullPointerException
61 throw new NullPointerException("NARG");
63 Set
<MarkedDependency
> depends
= new LinkedHashSet
<>();
64 for (MarkedDependency d
: __deps
)
66 throw new NullPointerException("NARG");
69 this._depends
= depends
;
73 * Returns the number of dependencies in the set.
75 * @return The number of dependencies.
80 return this._depends
.size();
88 public final boolean equals(Object __o
)
93 if (!(__o
instanceof DependencyInfo
))
96 return this._depends
.equals(((DependencyInfo
)__o
)._depends
);
104 public final int hashCode()
106 return this._depends
.hashCode();
110 * Checks if the dependency information is empty.
112 * @return If the dependency info is empty.
115 public final boolean isEmpty()
117 return this._depends
.isEmpty();
125 public Iterator
<MarkedDependency
> iterator()
127 return UnmodifiableIterator
.of(this._depends
.iterator());
131 * Matches this dependency information to see if any of the provided
132 * fields would statisfy the dependencies that are needed.
134 * @param __prov The provided information.
135 * @return The result of the match.
136 * @throws NullPointerException On null arguments.
139 public final MatchResult
match(ProvidedInfo __prov
)
140 throws NullPointerException
143 throw new NullPointerException("NARG");
145 // Remove matching dependencies from the input while keeping the
147 Set
<MarkedDependency
> depends
= new LinkedHashSet
<>(this._depends
),
148 matched
= new LinkedHashSet
<>();
149 for (MarkedProvided p
: __prov
)
151 for (Iterator
<MarkedDependency
> it
= depends
.iterator();
154 MarkedDependency d
= it
.next();
156 if (d
.matchesProvided(p
))
164 return new MatchResult(new DependencyInfo(matched
),
165 new DependencyInfo(depends
));
169 * Returns dependency information which contains no optional
172 * @return Dependency information with no optionals.
175 public final DependencyInfo
noOptionals()
177 // Ignore if there are no dependencies
178 Set
<MarkedDependency
> depends
= this._depends
;
179 if (depends
.isEmpty())
182 // Include only required dependencies
183 Set
<MarkedDependency
> instead
= new LinkedHashSet
<>();
184 for (MarkedDependency md
: depends
)
185 if (!md
.isOptional())
188 // There were no optional dependencies
189 if (depends
.size() == instead
.size())
191 return new DependencyInfo(instead
);
199 public final String
toString()
201 Reference
<String
> ref
= this._string
;
204 if (ref
== null || null == (rv
= ref
.get()))
205 this._string
= new WeakReference
<>((rv
= "Dependencies:" +
212 * Parses the given suite information and returns the dependency
215 * @param __info The suite information to parse.
216 * @return The parsed dependency information.
217 * @throws InvalidSuiteException If the dependencies is not correct.
218 * @throws NullPointerException On null arguments.
221 @SuppressWarnings("OverflowingLoopIndex")
222 public static final DependencyInfo
of(SuiteInfo __info
)
223 throws InvalidSuiteException
, NullPointerException
226 throw new NullPointerException("NARG");
228 Set
<MarkedDependency
> depends
= new LinkedHashSet
<>();
229 JavaManifestAttributes attr
= __info
.manifest().getMainAttributes();
232 // The CLDC library to use
233 value
= attr
.getValue("microedition-configuration");
236 value
= value
.trim();
238 // Old software may rely on using 1.0 values when that is illegal
239 if (value
.equals("1.0"))
240 depends
.add(new Configuration("CLDC-1.0"));
244 depends
.add(new Configuration(value
.trim()));
247 // Profiles needed to run
248 value
= attr
.getValue("microedition-profile");
250 for (String s
: StringUtils
.basicSplit(" \t", value
))
252 // Old software may rely on using the version directly
254 depends
.add(new Profile("MIDP-2.0"));
258 depends
.add(new Profile(s
));
261 // Parse entries in sequential order
262 SuiteType type
= __info
.type();
263 for (int i
= 1; i
>= 1; i
++)
265 // Stop if no more values are read
266 value
= attr
.getValue(type
.dependencyKey(i
));
271 depends
.add(new SuiteDependency(value
));
274 // MIDxlet (JSCL generally)
275 value
= attr
.getValue("midxlet-api");
277 for (String s
: StringUtils
.basicSplit(" \t", value
))
278 depends
.add(new Profile(s
));
281 value
= attr
.getValue("midxlet-opgl");
282 if (value
!= null && value
.equalsIgnoreCase("y"))
283 depends
.add(new SuiteDependency(SuiteDependencyType
.PROPRIETARY
,
284 SuiteDependencyLevel
.REQUIRED
,
285 "squirreljme.project@vendor-api-softbank-mexa;;"));
288 return new DependencyInfo(depends
);