001 /*
002 * $Id: LocalAddeEntry.java,v 1.33 2012/02/19 17:35:49 davep Exp $
003 *
004 * This file is part of McIDAS-V
005 *
006 * Copyright 2007-2012
007 * Space Science and Engineering Center (SSEC)
008 * University of Wisconsin - Madison
009 * 1225 W. Dayton Street, Madison, WI 53706, USA
010 * https://www.ssec.wisc.edu/mcidas
011 *
012 * All Rights Reserved
013 *
014 * McIDAS-V is built on Unidata's IDV and SSEC's VisAD libraries, and
015 * some McIDAS-V source code is based on IDV and VisAD source code.
016 *
017 * McIDAS-V is free software; you can redistribute it and/or modify
018 * it under the terms of the GNU Lesser Public License as published by
019 * the Free Software Foundation; either version 3 of the License, or
020 * (at your option) any later version.
021 *
022 * McIDAS-V is distributed in the hope that it will be useful,
023 * but WITHOUT ANY WARRANTY; without even the implied warranty of
024 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
025 * GNU Lesser Public License for more details.
026 *
027 * You should have received a copy of the GNU Lesser Public License
028 * along with this program. If not, see http://www.gnu.org/licenses.
029 */
030 package edu.wisc.ssec.mcidasv.servermanager;
031
032 import java.util.Collections;
033 import java.util.List;
034 import java.util.Map;
035
036 import org.slf4j.Logger;
037 import org.slf4j.LoggerFactory;
038
039 import edu.wisc.ssec.mcidasv.servermanager.AddeEntry.EntryType;
040
041 /**
042 *
043 *
044 *
045 */
046 public class LocalAddeEntry implements AddeEntry {
047
048 /** Friendly neighborhood logging object. */
049 static final Logger logger = LoggerFactory.getLogger(LocalAddeEntry.class);
050
051 /** Represents a {@literal "bad"} local ADDE entry. */
052 // seriously, don't use null unless you REALLY need it.
053 public static final LocalAddeEntry INVALID_ENTRY = new Builder("INVALID", "INVALID", "/dev/null", AddeFormat.INVALID).build();
054
055 /** Represents a {@literal "bad"} collection of local ADDE entries. */
056 public static final List<LocalAddeEntry> INVALID_ENTRIES = Collections.singletonList(INVALID_ENTRY);
057
058 /** */
059 private static final String CYGWIN_PREFIX = "/cygdrive/";
060
061 /** */
062 private static final int CYGWIN_PREFIX_LEN = CYGWIN_PREFIX.length();
063
064 /** */
065 private EntryStatus entryStatus = EntryStatus.INVALID;
066
067 // RESOLV.SRV FIELDS
068 /** N1 */
069 private final String group;
070
071 /** N2 */
072 // this value is built in a non-obvious way. plz to be dox.
073 private final String descriptor;
074
075 /** RT */
076 private final boolean realtime;
077
078 /** MCV */
079 private final AddeFormat format;
080
081 /** R1 */
082 private final String start;
083
084 /** R2 */
085 private final String end;
086
087 /** MASK */
088 private final String fileMask;
089
090 /** C */
091 private final String name;
092 // END RESOLV.SRV FIELDS
093
094 private String asStringId;
095
096 public enum ServerName {
097 AREA, AMSR, AMRR, GINI, FSDX, OMTP, LV1B, MODS, MODX, MOD4, MOD8,
098 MODR, MSGT, MTST, SMIN, TMIN, MD, INVALID;
099 }
100
101 /**
102 * The various kinds of local ADDE data understood by McIDAS-V, along with
103 * some helpful metadata.
104 *
105 * <p><ul>
106 * <li>{@literal "Human readable"} format names ({@link #friendlyName}).</li>
107 * <li>Optional tooltip description ({@link #tooltip}).</li>
108 * <li>Type of data ({@link #type}).</li>
109 * <li>File naming pattern {@link #fileFilter}.</li>
110 * </ul>
111 *
112 * <p>None of {@code AddeFormat}'s fields should contain {@code null}.
113 */
114 public enum AddeFormat {
115 MCIDAS_AREA(ServerName.AREA, "McIDAS AREA"),
116 MCIDAS_MD(ServerName.MD, "McIDAS MD", "McIDAS MD", EntryType.POINT),
117 AMSRE_L1B(ServerName.AMSR, "AMSR-E L 1b", "AMSR-E Level 1b"),
118 AMSRE_RAIN_PRODUCT(ServerName.AMRR, "AMSR-E Rain Product"),
119 GINI(ServerName.GINI, "GINI"),
120 LRIT_GOES9(ServerName.FSDX, "LRIT GOES-9", "EUMETCast LRIT GOES-9"),
121 LRIT_GOES10(ServerName.FSDX, "LRIT GOES-10", "EUMETCast LRIT GOES-10"),
122 LRIT_GOES11(ServerName.FSDX, "LRIT GOES-11", "EUMETCast LRIT GOES-11"),
123 LRIT_GOES12(ServerName.FSDX, "LRIT GOES-12", "EUMETCast LRIT GOES-12"),
124 LRIT_MET5(ServerName.FSDX, "LRIT MET-5", "EUMETCast LRIT MET-5"),
125 LRIT_MET7(ServerName.FSDX, "LRIT MET-7", "EUMETCast LRIT MET-7"),
126 LRIT_MTSAT1R(ServerName.FSDX, "LRIT MTSAT-1R", "EUMETCast LRIT MTSAT-1R"),
127 METEOSAT_OPENMTP(ServerName.OMTP, "Meteosat OpenMTP"),
128 METOP_AVHRR_L1B(ServerName.LV1B, "Metop AVHRR L 1b", "Metop AVHRR Level 1b"),
129 MODIS_L1B_MOD02(ServerName.MODS, "MODIS MOD 02 - Level-1B Calibrated Geolocated Radiances", "MODIS Level 1b"),
130 MODIS_L2_MOD06(ServerName.MODX, "MODIS MOD 06 - Cloud Product", "MODIS Level 2 (Cloud Top Properties)"),
131 MODIS_L2_MOD07(ServerName.MODX, "MODIS MOD 07 - Atmospheric Profiles", "MODIS Level 2 (Atmospheric Profile)"),
132 MODIS_L2_MOD35(ServerName.MODX, "MODIS MOD 35 - Cloud Mask", "MODIS Level 2 (Cloud Mask)"),
133 MODIS_L2_MOD04(ServerName.MOD4, "MODIS MOD 04 - Aerosol Product", "MODIS Level 2 (Aerosol)"),
134 MODIS_L2_MOD28(ServerName.MOD8, "MODIS MOD 28 - Sea Surface Temperature", "MODIS Level 2 (Sea Surface Temperature)"),
135 MODIS_L2_MODR(ServerName.MODR, "MODIS MOD R - Corrected Reflectance", "MODIS Level 2 (Corrected Reflectance)"),
136 MSG_HRIT_FD(ServerName.MSGT, "MSG HRIT FD", "MSG HRIT (Full Disk)"),
137 MSG_HRIT_HRV(ServerName.MSGT, "MSG HRIT HRV", "MSG HRIT (High Resolution Visible)"),
138 MTSAT_HRIT(ServerName.MTST, "MTSAT HRIT"),
139 NOAA_AVHRR_L1B(ServerName.LV1B, "NOAA AVHRR L 1b", "NOAA AVHRR Level 1b"),
140 SSMI(ServerName.SMIN, "SSMI", "Terrascan netCDF (SMIN)"),
141 TRMM(ServerName.TMIN, "TRMM", "Terrascan netCDF (TMIN)"),
142 INVALID(ServerName.INVALID, "", "", EntryType.INVALID);
143
144 /** Name of the McIDAS-X server. */
145 private final ServerName servName;
146
147 /** {@literal "Human readable"} format name. This is returned by {@link #toString()}. */
148 private final String friendlyName;
149
150 /** Description of the format. */
151 private final String tooltip;
152
153 /** Data type. Corresponds to {@code TYPE} in {@literal "RESOLV.SRV"}. */
154 private final EntryType type;
155
156 /**
157 * Filename pattern used when listing files in a directory.
158 * If {@link #servName} is {@link ServerName#MSGT} then
159 * {@literal "*PRO*"} is used, otherwise {@literal "*"}.
160 */
161 private final String fileFilter;
162
163 /**
164 * Builds an {@literal "ADDE format"} and its associated metadata in
165 * a typesafe way.
166 *
167 * @param servName {@link ServerName} that McIDAS-X uses for this format.
168 * @param friendlyName {@literal "Human readable"} name of the format; returned by {@link #toString()}.
169 * @param tooltip If non-empty, this is used as a tooltip in the local entry editor.
170 * @param type {@link EntryType} used by this format.
171 */
172 private AddeFormat(final ServerName servName, final String friendlyName, final String tooltip, final EntryType type) {
173 this.servName = servName;
174 this.friendlyName = friendlyName;
175 this.tooltip = tooltip;
176 this.type = type;
177 this.fileFilter = (servName != ServerName.MSGT) ? "*" : "*PRO*";
178 }
179
180 /**
181 * Builds an {@literal "imagery ADDE Format"} <b>without</b> a tooltip.
182 *
183 * @param servName {@link ServerName} that McIDAS-X uses for this format.
184 * @param friendlyName {@literal "Human readable"} name of the format; returned by {@link #toString()}.
185 */
186 private AddeFormat(final ServerName servName, final String friendlyName) {
187 this(servName, friendlyName, "", EntryType.IMAGE);
188 }
189
190 /**
191 * Builds an {@literal "imagery ADDE Format"} <b>with</b> a tooltip.
192 *
193 * @param servName {@link ServerName} that McIDAS-X uses for this format.
194 * @param friendlyName {@literal "Human readable"} name of the format; returned by {@link #toString()}.
195 * @param tooltip If non-empty, this is used as a tooltip in the local entry editor.
196 */
197 private AddeFormat(final ServerName servName, final String friendlyName, final String tooltip) {
198 this(servName, friendlyName, tooltip, EntryType.IMAGE);
199 }
200
201 /**
202 * Gets the McIDAS-X {@link ServerName} for this format.
203 *
204 * @return Either the name of this format's McIDAS-X server, or {@link ServerName#INVALID}.
205 */
206 public ServerName getServerName() {
207 return servName;
208 }
209
210 /**
211 * Gets the tooltip text to use in the server manager GUI for this
212 * format.
213 *
214 * @return Text to use as a GUI tooltip. Cannot be {@code null}, though
215 * empty {@code String} values are permitted.
216 */
217 public String getTooltip() {
218 return tooltip;
219 }
220
221 /**
222 * Gets the type of data used by this format. This value dictates the
223 * chooser(s) where this format can appear.
224 *
225 * @return One of {@link EntryType}, or {@link EntryType#INVALID}.
226 */
227 public EntryType getType() {
228 return type;
229 }
230
231 /**
232 * Gets the string used to filter out files that match this format.
233 *
234 * @return Either a specialized {@code String}, like {@literal "*PRO*"} or {@literal "*"}.
235 */
236 public String getFileFilter() {
237 return fileFilter;
238 }
239
240 /**
241 * Gets the {@code String} representation of this format.
242 *
243 * @return the value of {@link #friendlyName}.
244 */
245 @Override public String toString() {
246 return friendlyName;
247 }
248 }
249
250 /**
251 *
252 *
253 * @param builder
254 *
255 * @see LocalAddeEntry.Builder
256 */
257 private LocalAddeEntry(final Builder builder) {
258 this.group = builder.group;
259 this.descriptor = builder.descriptor;
260 this.realtime = builder.realtime;
261 this.format = builder.format;
262 this.fileMask = builder.mask;
263 this.name = builder.name;
264 this.start = builder.start;
265 this.end = builder.end;
266 this.entryStatus = builder.status;
267 logger.debug("created local: {}", this);
268 }
269
270 @Override public AddeAccount getAccount() {
271 return RemoteAddeEntry.DEFAULT_ACCOUNT;
272 }
273
274 @Override public String getAddress() {
275 return "localhost";
276 }
277
278 @Override public EntrySource getEntrySource() {
279 return EntrySource.USER;
280 }
281
282 @Override public EntryStatus getEntryStatus() {
283 return entryStatus;
284 }
285
286 @Override public String getEntryText() {
287 return "localhost/"+getGroup();
288 }
289
290 @Override public EntryType getEntryType() {
291 return format.getType();
292 }
293
294 @Override public EntryValidity getEntryValidity() {
295 return (isValid()) ? EntryValidity.VERIFIED : EntryValidity.INVALID;
296 }
297
298 // TODO(jon): fix this noop
299 @Override public String getEntryAlias() {
300 return "";
301 }
302
303 // TODO(jon): fix this noop
304 @Override public void setEntryAlias(final String newAlias) {
305 if (newAlias == null) {
306 throw new NullPointerException("Null aliases are not allowable.");
307 }
308 }
309
310 @Override public void setEntryStatus(EntryStatus newStatus) {
311 entryStatus = newStatus;
312 }
313
314 @Override public String getGroup() {
315 return group;
316 }
317
318 @Override public String getName() {
319 return name;
320 }
321
322 /**
323 * Gets the ADDE descriptor for the current local ADDE entry.
324 *
325 * @return ADDE descriptor (corresponds to the {@literal "N2"} section of a RESOLV.SRV
326 * entry).
327 */
328 public String getDescriptor() {
329 return descriptor;
330 }
331
332 /**
333 * Gets the ADDE dataset format for the current local ADDE entry.
334 *
335 * @return ADDE format (corresponds to the {@literal "MCV"} section of a RESOLV.SRV
336 * entry).
337 */
338 public AddeFormat getFormat() {
339 return format;
340 }
341
342 /**
343 * Gets the ADDE file mask for the current local ADDE entry.
344 *
345 * @return ADDE file mask (corresponds to the {@literal "MASK"} section of a RESOLV.SRV
346 * entry).
347 */
348 public String getMask() {
349 return fileMask;
350 }
351
352 /**
353 * Gets the ADDE file mask for the current local ADDE entry.
354 *
355 * @return ADDE file mask (corresponds to the {@literal "MASK"} section of a RESOLV.SRV
356 * entry).
357 */
358 public String getFileMask() {
359 return fileMask;
360 }
361
362 /**
363 * Gets the ADDE realtime status of the current local ADDE entry.
364 *
365 * @return Whether or not the current dataset is {@literal "realtime"}.
366 * Corresponds to the {@literal "RT"} section of a RESOLV.SRV entry.
367 */
368 public boolean getRealtime() {
369 return realtime;
370 }
371
372 /**
373 * Gets the starting number of the current local ADDE dataset.
374 *
375 * @return Corresponds to the {@literal "R1"} section of a RESOLV.SRV entry.
376 */
377 public String getStart() {
378 return start;
379 }
380
381 /**
382 * Gets the ending number of the current local ADDE dataset.
383 *
384 * @return Corresponds to the {@literal "R2"} section of a RESOLV.SRV entry.
385 */
386 public String getEnd() {
387 return end;
388 }
389
390 /**
391 * Tests the current local ADDE dataset for validity.
392 *
393 * @return {@code true} iff {@link #group} and {@link #name} are not empty.
394 */
395 public boolean isValid() {
396 // return !((group.isEmpty()) || (descriptor.isEmpty()) || (name.isEmpty()));
397 return !((group.isEmpty()) || (name.isEmpty()));
398 }
399
400 /**
401 * Gets the local ADDE dataset's realtime status as a value suitable for
402 * RESOLV.SRV (one of {@literal "Y"} or {@literal "N"}).
403 *
404 * @return RESOLV.SRV-friendly representation of the current realtime status.
405 */
406 public String getRealtimeAsString() {
407 return (realtime) ? "Y" : "N";
408 }
409
410 /**
411 * @see LocalAddeEntry#generateHashCode(String, String, String, AddeFormat)
412 */
413 @Override public int hashCode() {
414 return generateHashCode(name, group, fileMask, format);
415 }
416
417 /**
418 * Checks a given object for equality with the current {@code LocalAddeEntry}
419 * instance.
420 *
421 * @param obj Object to check. {@code null} values allowed.
422 *
423 * @return {@code true} if {@code obj} is {@literal "equal"} to the current
424 * {@code LocalAddeEntry} instance.
425 */
426 @Override public boolean equals(Object obj) {
427 if (this == obj) {
428 return true;
429 }
430 if (obj == null) {
431 return false;
432 }
433 if (!(obj instanceof LocalAddeEntry)) {
434 return false;
435 }
436 LocalAddeEntry other = (LocalAddeEntry) obj;
437 if (fileMask == null) {
438 if (other.fileMask != null) {
439 return false;
440 }
441 } else if (!fileMask.equals(other.fileMask)) {
442 return false;
443 }
444 if (format == null) {
445 if (other.format != null) {
446 return false;
447 }
448 } else if (!format.toString().equals(other.format.toString())) {
449 return false;
450 }
451 if (group == null) {
452 if (other.group != null) {
453 return false;
454 }
455 } else if (!group.equals(other.group)) {
456 return false;
457 }
458 if (name == null) {
459 if (other.name != null) {
460 return false;
461 }
462 } else if (!name.equals(other.name)) {
463 return false;
464 }
465 return true;
466 }
467
468 @Override public String asStringId() {
469 if (asStringId == null) {
470 asStringId = "localhost!"+group+'!'+EntryType.IMAGE.name()+'!'+name;
471 }
472 return asStringId;
473 }
474
475 @Override public String toString() {
476 return String.format(
477 "[LocalAddeEntry@%x: name=%s, group=%s, fileMask=\"%s\", descriptor=%s, serverName=%s, format=%s, description=%s, type=%s, status=%s]",
478 hashCode(), name, group, fileMask, descriptor, format.getServerName().name(), format.name(), format.getTooltip(), format.getType(), entryStatus.name());
479
480 }
481
482 public static int generateHashCode(final LocalAddeEntry entry) {
483 return generateHashCode(entry.getName(), entry.getGroup(), entry.getMask(), entry.getFormat());
484 }
485
486 public static int generateHashCode(String name, String group, String fileMask, AddeFormat format) {
487 final int prime = 31;
488 int result = 1;
489 result = prime * result
490 + ((fileMask == null) ? 0 : fileMask.hashCode());
491 result = prime * result + ((format == null) ? 0 : format.toString().hashCode());
492 result = prime * result + ((group == null) ? 0 : group.hashCode());
493 result = prime * result + ((name == null) ? 0 : name.hashCode());
494 return result;
495 }
496
497 /**
498 * A builder of (mostly) immutable {@link LocalAddeEntry} instances.
499 *
500 * <p>Usage example: <pre> {@code
501 * LocalAddeEntry entry = new LocalAddeEntry
502 * .Builder(group, name, format, mask)
503 * .realtime("Y")
504 * .range(start, end)
505 * .type(EntryType.POINT)
506 * .build();}</pre>
507 *
508 * Only the values required by the Builder constructor are required.
509 */
510 public static class Builder {
511 // required
512 /** Corresponds to RESOLV.SRV's {@literal "N1"} section. */
513 private final String group;
514
515 /** Corresponds to RESOLV.SRV's {@literal "C"} section. */
516 private final String name;
517
518 /** Corresponds to RESOLV.SRV's {@literal "MCV"} section. */
519 private final AddeFormat format;
520
521 /** Corresponds to RESOLV.SRV's {@literal "MASK"} section. */
522 private final String mask;
523
524 // generated
525 private String descriptor;
526
527 // optional
528 /**
529 * Corresponds to RESOLV.SRV's {@literal "RT"} section.
530 * Defaults to {@code false}.
531 */
532 private boolean realtime = false;
533
534 /**
535 * Corresponds to RESOLV.SRV's {@literal "R1"} section.
536 * Defaults to {@literal "1"}.
537 */
538 private String start = "1";
539
540 /**
541 * Corresponds to RESOLV.SRV's {@literal "R2"} section.
542 * Defaults to {@literal "999999"}.
543 */
544 private String end = "999999";
545
546 /**
547 * Defaults to {@link edu.wisc.ssec.mcidasv.servermanager.AddeEntry.EntryStatus#INVALID}.
548 */
549 private EntryStatus status = EntryStatus.INVALID;
550
551 /**
552 * Corresponds to RESOLV.SRV's {@literal "TYPE"} section.
553 * Defaults to {@link EntryType#IMAGE}.
554 */
555 private EntryType type = EntryType.IMAGE;
556
557 /**
558 * Corresponds to RESOLV.SRV's {@literal "K"} section.
559 * Defaults to {@literal "NOT_SET"}.
560 */
561 private String kind = "NOT_SET";
562
563 /**
564 * Defaults to {@link ServerName#INVALID}.
565 */
566 private ServerName safeKind = ServerName.INVALID;
567
568 public Builder(final Map<String, String> map) {
569 if (!map.containsKey("C") || !map.containsKey("N1") || !map.containsKey("MASK") || !map.containsKey("MCV")) {
570 throw new IllegalArgumentException("Cannot build a LocalAddeEntry without the following keys: C, N1, MASK, and MCV.");
571 }
572
573 this.name = map.get("C");
574 this.group = map.get("N1");
575 this.mask = map.get("MASK");
576 this.format = EntryTransforms.strToAddeFormat(map.get("MCV"));
577
578 // descriptor(map.get("N2"));
579 type(EntryTransforms.strToEntryType(map.get("TYPE")));
580 kind(map.get("K").toUpperCase());
581 realtime(map.get("RT"));
582 start(map.get("R1"));
583 end(map.get("R2"));
584 }
585
586 /**
587 * Creates a new {@code LocalAddeEntry} {@literal "builder"} with the
588 * required fields for a {@code LocalAddeEntry} object.
589 *
590 * @param name
591 * @param group
592 * @param mask
593 * @param format
594 */
595 public Builder(final String name, final String group, final String mask, final AddeFormat format) {
596 this.name = name;
597 this.group = group;
598 this.mask = mask;
599 this.format = format;
600 }
601
602 /**
603 * This method is currently a no-op.
604 *
605 * @param descriptor
606 *
607 * @return {@code LocalAddeEntry.Builder} with ADDE descriptor.
608 */
609 public Builder descriptor(final String descriptor) {
610 // if (descriptor != null) {
611 // this.descriptor = descriptor;
612 // }
613 return this;
614 }
615
616 /**
617 *
618 *
619 * @param realtimeAsStr
620 *
621 * @return {@code LocalAddeEntry.Builder} with ADDE realtime flag.
622 */
623 // looks like mcidasx understands ("Y"/"N"/"A")
624 // should probably ignore case and accept "YES"/"NO"/"ARCHIVE"
625 // in addition to the normal boolean conversion from String
626 public Builder realtime(final String realtimeAsStr) {
627 if (realtimeAsStr == null) {
628 return this;
629 }
630
631 if ("Y".equalsIgnoreCase(realtimeAsStr) || "YES".equalsIgnoreCase(realtimeAsStr)) {
632 this.realtime = true;
633 } else {
634 this.realtime = Boolean.valueOf(realtimeAsStr);
635 }
636 return this;
637 }
638
639 /**
640 *
641 *
642 * @param realtime
643 *
644 * @return {@code LocalAddeEntry.Builder} with ADDE realtime flag.
645 */
646 public Builder realtime(final boolean realtime) {
647 this.realtime = realtime;
648 return this;
649 }
650
651 /**
652 *
653 *
654 * @param type
655 *
656 * @return {@code LocalAddeEntry.Builder} with ADDE data type.
657 */
658 // my assumption is that if "format" is known, you can infer "type"
659 public Builder type(final EntryType type) {
660 if (type != null) {
661 this.type = type;
662 }
663 return this;
664 }
665
666 /**
667 *
668 *
669 * @param kind
670 *
671 * @return {@code LocalAddeEntry.Builder} with ADDE kind.
672 */
673 // my assumption is that if "format" is known, you can infer "kind"
674 public Builder kind(final String kind) {
675 if (kind == null) {
676 return this;
677 }
678
679 this.kind = kind;
680 try {
681 this.safeKind = ServerName.valueOf(kind);
682 } catch (IllegalArgumentException e) {
683 this.safeKind = ServerName.INVALID;
684 }
685 return this;
686 }
687
688 /**
689 *
690 *
691 * @param start
692 *
693 * @return {@code LocalAddeEntry.Builder} with ADDE dataset {@literal "start"}.
694 */
695 public Builder start(final String start) {
696 if (start != null) {
697 this.start = start;
698 }
699 return this;
700 }
701
702 /**
703 *
704 *
705 * @param end
706 *
707 * @return {@code LocalAddeEntry.Builder} with ADDE dataset {@literal "end"}.
708 */
709 public Builder end(final String end) {
710 if (end != null) {
711 this.end = end;
712 }
713 return this;
714 }
715
716 /**
717 *
718 *
719 * @param start
720 * @param end
721 *
722 * @return {@code LocalAddeEntry.Builder} with ADDE dataset {@literal "start" and "end"} values.
723 */
724 public Builder range(final String start, final String end) {
725 if (start != null && end != null) {
726 this.start = start;
727 this.end = end;
728 }
729 return this;
730 }
731
732 /**
733 *
734 *
735 * @param status
736 *
737 * @return {@code LocalAddeEntry.Builder} with {@link AddeEntry.EntryStatus}.
738 */
739 public Builder status(final String status) {
740 if (status != null && status.length() > 0) {
741 this.status = EntryTransforms.strToEntryStatus(status);
742 }
743 return this;
744 }
745
746 /**
747 *
748 *
749 * @param status
750 *
751 * @return {@code LocalAddeEntry.Builder} with {@link AddeEntry.EntryStatus}.
752 */
753 public Builder status(final EntryStatus status) {
754 if (status != null) {
755 this.status = status;
756 }
757 return this;
758 }
759
760 /**
761 *
762 *
763 * @return New {@code LocalAddeEntry} instance.
764 */
765 public LocalAddeEntry build() {
766 // apparently need to hack up the descriptor for certain formats
767 switch (format) {
768 case MSG_HRIT_FD: this.descriptor = "FD"; break;
769 case MSG_HRIT_HRV: this.descriptor = "HRV"; break;
770 case LRIT_GOES9: this.descriptor = "GOES9"; break;
771 case LRIT_GOES10: this.descriptor = "GOES10"; break;
772 case LRIT_GOES11: this.descriptor = "GOES11"; break;
773 case LRIT_GOES12: this.descriptor = "GOES12"; break;
774 case LRIT_MET5: this.descriptor = "MET5"; break;
775 case LRIT_MET7: this.descriptor = "MET7"; break;
776 case LRIT_MTSAT1R: this.descriptor = "MTSAT1R"; break;
777 default:
778 this.descriptor = Integer.toHexString(generateHashCode(name, group, mask, format));
779 break;
780 }
781 return new LocalAddeEntry(this);
782 }
783 }
784 }