Offload int[] to byte[].
[SquirrelJME.git] / modules / cldc-compact / src / main / java / cc / squirreljme / jvm / suite / DependencyInfo.java
blob2f3ccef0a58da92689565573d04cb01b58074218
1 // -*- Mode: Java; indent-tabs-mode: t; tab-width: 4 -*-
2 // ---------------------------------------------------------------------------
3 // SquirrelJME
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;
21 import java.util.Set;
23 /**
24 * This contains the information which specifies all of the dependencies which
25 * and application depends on.
27 * @since 2017/11/30
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;
38 /**
39 * Initializes the dependency information.
41 * @param __deps The dependencies to depend on.
42 * @since 2017/12/31
44 public DependencyInfo(MarkedDependency... __deps)
46 this(Arrays.<MarkedDependency>asList((__deps == null ?
47 new MarkedDependency[0] : __deps)));
50 /**
51 * Initializes the dependency information.
53 * @param __deps The dependencies to use.
54 * @throws NullPointerException On null arguments.
55 * @since 2017/12/31
57 public DependencyInfo(Collection<MarkedDependency> __deps)
58 throws NullPointerException
60 if (__deps == null)
61 throw new NullPointerException("NARG");
63 Set<MarkedDependency> depends = new LinkedHashSet<>();
64 for (MarkedDependency d : __deps)
65 if (d == null)
66 throw new NullPointerException("NARG");
67 else
68 depends.add(d);
69 this._depends = depends;
72 /**
73 * Returns the number of dependencies in the set.
75 * @return The number of dependencies.
76 * @since 2022/02/03
78 public int count()
80 return this._depends.size();
83 /**
84 * {@inheritDoc}
85 * @since 2017/12/31
87 @Override
88 public final boolean equals(Object __o)
90 if (this == __o)
91 return true;
93 if (!(__o instanceof DependencyInfo))
94 return false;
96 return this._depends.equals(((DependencyInfo)__o)._depends);
99 /**
100 * {@inheritDoc}
101 * @since 2017/12/31
103 @Override
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.
113 * @since 2017/11/30
115 public final boolean isEmpty()
117 return this._depends.isEmpty();
121 * {@inheritDoc}
122 * @since 2022/02/03
124 @Override
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.
137 * @since 2017/11/30
139 public final MatchResult match(ProvidedInfo __prov)
140 throws NullPointerException
142 if (__prov == null)
143 throw new NullPointerException("NARG");
145 // Remove matching dependencies from the input while keeping the
146 // matching ones
147 Set<MarkedDependency> depends = new LinkedHashSet<>(this._depends),
148 matched = new LinkedHashSet<>();
149 for (MarkedProvided p : __prov)
151 for (Iterator<MarkedDependency> it = depends.iterator();
152 it.hasNext();)
154 MarkedDependency d = it.next();
156 if (d.matchesProvided(p))
158 matched.add(d);
159 it.remove();
164 return new MatchResult(new DependencyInfo(matched),
165 new DependencyInfo(depends));
169 * Returns dependency information which contains no optional
170 * dependencies.
172 * @return Dependency information with no optionals.
173 * @since 2017/11/30
175 public final DependencyInfo noOptionals()
177 // Ignore if there are no dependencies
178 Set<MarkedDependency> depends = this._depends;
179 if (depends.isEmpty())
180 return this;
182 // Include only required dependencies
183 Set<MarkedDependency> instead = new LinkedHashSet<>();
184 for (MarkedDependency md : depends)
185 if (!md.isOptional())
186 instead.add(md);
188 // There were no optional dependencies
189 if (depends.size() == instead.size())
190 return this;
191 return new DependencyInfo(instead);
195 * {@inheritDoc}
196 * @since 2017/12/31
198 @Override
199 public final String toString()
201 Reference<String> ref = this._string;
202 String rv;
204 if (ref == null || null == (rv = ref.get()))
205 this._string = new WeakReference<>((rv = "Dependencies:" +
206 this._depends));
208 return rv;
212 * Parses the given suite information and returns the dependency
213 * information.
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.
219 * @since 2017/11/20
221 @SuppressWarnings("OverflowingLoopIndex")
222 public static final DependencyInfo of(SuiteInfo __info)
223 throws InvalidSuiteException, NullPointerException
225 if (__info == null)
226 throw new NullPointerException("NARG");
228 Set<MarkedDependency> depends = new LinkedHashSet<>();
229 JavaManifestAttributes attr = __info.manifest().getMainAttributes();
230 String value;
232 // The CLDC library to use
233 value = attr.getValue("microedition-configuration");
234 if (value != null)
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"));
242 // Decode otherwise
243 else
244 depends.add(new Configuration(value.trim()));
247 // Profiles needed to run
248 value = attr.getValue("microedition-profile");
249 if (value != null)
250 for (String s : StringUtils.basicSplit(" \t", value))
252 // Old software may rely on using the version directly
253 if (s.equals("2.0"))
254 depends.add(new Profile("MIDP-2.0"));
256 // Decode otherwise
257 else
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));
267 if (value == null)
268 break;
270 // Decode dependency
271 depends.add(new SuiteDependency(value));
274 // MIDxlet (JSCL generally)
275 value = attr.getValue("midxlet-api");
276 if (value != null)
277 for (String s : StringUtils.basicSplit(" \t", value))
278 depends.add(new Profile(s));
280 // MEXA OpenGL
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;;"));
287 // Build
288 return new DependencyInfo(depends);