public void releaseObject(DragDropEvent ddEvent) { Map<String, String> params = FacesContext.getCurrentInstance().getExternalContext().getRequestParameterMap(); String left = params.get("class"); String[] sClass = left.split(" "); int col = 0; int ligne = 0; int item = 0; for (String s : sClass) { if (StringUtils.startsWith(s, "colonne_")) { String c = s.replace("colonne_", ""); col = Integer.valueOf(c); } if (StringUtils.startsWith(s, "ligne_")) { String c = s.replace("ligne_", ""); ligne = Integer.valueOf(c); } if (StringUtils.startsWith(s, "position_")) { String c = s.replace("position_", ""); item = Integer.valueOf(c); } } if (col == 0 && ligne == 0) { pioche.remove(item); } else { Cell c = list.get(ligne).get(col); c.setType(Cell.CELL_EMPTY); c.setAngle(-1); } System.out.println("drop"); }
public void putInPioche(DragDropEvent ddEvent) { Map<String, String> params = FacesContext.getCurrentInstance().getExternalContext().getRequestParameterMap(); String left = params.get("class"); String[] sClass = left.split(" "); String idTmp = ""; int colTmp = -1; int ligneTmp = 0; for (String s : sClass) { if (StringUtils.startsWith(s, "colonne_")) { String c = s.replace("colonne_", ""); colTmp = Integer.valueOf(c); } if (StringUtils.startsWith(s, "ligne_")) { String c = s.replace("ligne_", ""); ligneTmp = Integer.valueOf(c); } if (StringUtils.startsWith(s, "id_")) { idTmp = s.replace("id_", ""); } } if (colTmp != -1) { Cell c = list.get(ligneTmp).get(colTmp); c.setType(Cell.CELL_EMPTY); c.setAngle(-1); } if (idTmp.equals(Cell.CELL_MIRROR) || idTmp.equals(Cell.CELL_SPLIT)) { Cell c = new Cell(idTmp); c.setAngle(0); pioche.add(c); } }
/** * Every overload of {@link Reader#read()} method delegates to this one so it is enough to * override only this one. <br> * To skip invalid characters this method shifts only valid chars to left and returns decreased * value of the original read method. So after last valid character there will be some unused * chars in the buffer. * * @return Number of read valid characters or <code>-1</code> if end of the underling reader was * reached. */ @Override public int read(char[] cbuf, int off, int len) throws IOException { int read = super.read(cbuf, off, len); // check for end if (read == -1) { return -1; } // target position int pos = off - 1; int entityStart = -1; for (int readPos = off; readPos < off + read; readPos++) { boolean useChar = true; switch (cbuf[readPos]) { case '&': pos++; entityStart = readPos; break; case ';': pos++; if (entityStart >= 0) { int entityLength = readPos - entityStart + 1; if (entityLength <= 5) { String entity = new String(cbuf, entityStart, entityLength); if (StringUtils.startsWith(entity, "&#")) { String numberString = StringUtils.substringBetween(entity, "&#", ";"); final int value; if (StringUtils.startsWith(numberString, "x")) { value = Integer.parseInt(numberString.substring(1), 16); } else { value = Integer.parseInt(numberString); } if (!isValidXMLChar((char) value)) { pos -= entityLength; useChar = false; } } } } break; default: if (isValidXMLChar(cbuf[readPos])) { pos++; } else { continue; } } // copy, and skip unwanted characters if (pos < readPos && useChar) { cbuf[pos] = cbuf[readPos]; } } return pos - off + 1; }
public void dropObject(DragDropEvent ddEvent) { Map<String, String> params = FacesContext.getCurrentInstance().getExternalContext().getRequestParameterMap(); String ligne = getParam("ligne"); String colonne = getParam("colonne"); String left = params.get("class"); String[] sClass = left.split(" "); int colTmp = -1; int ligneTmp = 0; int item = -1; String idTmp = ""; for (String s : sClass) { if (StringUtils.startsWith(s, "colonne_")) { String c = s.replace("colonne_", ""); colTmp = Integer.valueOf(c); } if (StringUtils.startsWith(s, "ligne_")) { String c = s.replace("ligne_", ""); ligneTmp = Integer.valueOf(c); } if (StringUtils.startsWith(s, "id_")) { idTmp = s.replace("id_", ""); } if (StringUtils.startsWith(s, "position_")) { String c = s.replace("position_", ""); item = Integer.valueOf(c); } } int x = Integer.valueOf(ligne); int y = Integer.valueOf(colonne); String id; if (StringUtils.isEmpty(idTmp)) { id = params.get("dragId"); id = id.replaceAll("FormContent:", ""); } else { id = idTmp; if (item != -1) pioche.remove(item); } if (colTmp == -1) { Cell newCell = list.get(x).get(y); newCell.setType(id); newCell.setAngle(0); } else { Cell c = list.get(ligneTmp).get(colTmp); Cell newCell = list.get(x).get(y); newCell.setType(c.getType()); newCell.setAngle(c.getAngle()); c.setType(Cell.CELL_EMPTY); c.setAngle(-1); } }
/** * @param color * @return whether the color is testable, i.e defined as a rgb color */ public static boolean isColorTestable(final String color) { return !StringUtils.contains(color, BACKGROUND_IMAGE_KEY) && !StringUtils.contains(color, GRADIENT_KEY) && !StringUtils.contains(color, ALPHA_COLOR_KEY) && !StringUtils.equalsIgnoreCase(color, TRANSPARENT_KEY) && StringUtils.startsWith(color, RGB_COLOR_KEY); }
/** * Converts the resource type to an absolute path. If it does not start with "/" the resource is * resolved via search paths using resource resolver. If not matching resource is found it is * returned unchanged. * * @param resourceType Resource type * @return Absolute resource type */ public static String makeAbsolute(String resourceType, ResourceResolver resourceResolver) { if (StringUtils.isEmpty(resourceType) || StringUtils.startsWith(resourceType, "/")) { return resourceType; } // first try to resolve path via component manager - because on publish instance the original // resource may not accessible ComponentManager componentManager = resourceResolver.adaptTo(ComponentManager.class); if (componentManager != null) { Component component = componentManager.getComponent(resourceType); if (component != null) { return component.getPath(); } else { return resourceType; } } // otherwise use resource resolver directly Resource resource = resourceResolver.getResource(resourceType); if (resource != null) { return resource.getPath(); } else { return resourceType; } }
@Override @SuppressWarnings("unchecked") public ActionForward refresh( ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception { ActionForward forward = super.refresh(mapping, form, request, response); String prefix = getSpecialReviewService().getProtocolSaveLocationPrefix(request.getParameterMap()); InstitutionalProposalForm proposalForm = (InstitutionalProposalForm) form; InstitutionalProposalSpecialReview proposalSpecialReview = null; if (StringUtils.startsWith(prefix, "specialReviewHelper.newSpecialReview")) { proposalSpecialReview = proposalForm.getSpecialReviewHelper().getNewSpecialReview(); } else { int index = getSpecialReviewService().getProtocolIndex(prefix); if (index != -1) { proposalSpecialReview = proposalForm .getInstitutionalProposalDocument() .getInstitutionalProposal() .getSpecialReviews() .get(index); } } proposalForm.getSpecialReviewHelper().prepareProtocolLinkViewFields(proposalSpecialReview); return forward; }
public static final String id(String id) { if (StringUtils.startsWith(id, prefix)) { return prefix.concat(Utils.noSpaces(Utils.stripAndTrim(id.replaceAll(prefix, ""), " "), "-")); } else if (id != null) { return prefix.concat(Utils.noSpaces(Utils.stripAndTrim(id, " "), "-")); } else { return null; } }
/** * Checks whether the given String is a parsable number. * * <p>Parsable numbers include those Strings understood by {@link Integer#parseInt(String)}, * {@link Long#parseLong(String)}, {@link Float#parseFloat(String)} or {@link * Double#parseDouble(String)}. This method can be used instead of catching {@link * java.text.ParseException} when calling one of those methods. * * <p>Hexadecimal and scientific notations are <strong>not</strong> considered parsable. See * {@link #isNumber(String)} on those cases. * * <p>{@code Null} and empty String will return <code>false</code>. * * @param str the String to check. * @return {@code true} if the string is a parsable number. * @since 3.4 */ public static boolean isParsable(final String str) { if (StringUtils.endsWith(str, ".")) { return false; } if (StringUtils.startsWith(str, "-")) { return isDigits(StringUtils.replaceOnce(str.substring(1), ".", StringUtils.EMPTY)); } else { return isDigits(StringUtils.replaceOnce(str, ".", StringUtils.EMPTY)); } }
private StepCandidate findComposedCandidate( String composedStep, List<StepCandidate> allCandidates) { for (StepCandidate candidate : allCandidates) { if (StringUtils.startsWith(composedStep, candidate.getStartingWord()) && (StringUtils.endsWith(composedStep, candidate.getPatternAsString()) || candidate.matches(composedStep))) { return candidate; } } return null; }
private void hashPassword(org.molgenis.omx.auth.MolgenisUser user) { // if password already encrypted, nothing changed -> return if (StringUtils.startsWith(user.getPassword(), "md5_")) return; try { PasswordHasher md5 = new PasswordHasher(); String newPassword = md5.toMD5(user.getPassword()); user.setPassword(newPassword); } catch (NoSuchAlgorithmException e) { throw new RuntimeException(e); } }
@Override public void execute() throws Exception { Path destinationFile = task.getDestinationFile().toAbsolutePath(); if (!Files.isReadable(destinationFile) || Files.size(destinationFile) == 0) { String contentType = HTTPClient.getInstance() .downloadToFile( new WebResource(task.getUrl(), task.getReferer()), destinationFile, 0); if (task.isImage() && !StringUtils.startsWith(contentType, "image/")) { ErrorManager.getInstance().reportError(String.format("%s is not an image", task.getUrl())); Files.delete(destinationFile); } } }
@Test public void testCampusCodeSearchResults() { service.setBusinessObjectClass(Unit.class); Map<String, String> fieldValues = new HashMap<String, String>(); fieldValues.put(CAMPUS_CODE_FIELD, CAMPUS_CODE); List<? extends BusinessObject> searchResults = service.getSearchResults(fieldValues); assertEquals(SEARCH_RESULTS_CAMPUS_CODE_COUNT, searchResults.size()); for (BusinessObject searchResult : searchResults) { Unit unit = (Unit) searchResult; assertTrue(StringUtils.startsWith(unit.getUnitNumber(), CAMPUS_CODE)); } }
public List<FormattedText> get(String source) { List<String> splitedStringList = split(source); if (splitedStringList == null) { return null; } List<FormattedText> formattedTextList = new ArrayList<FormattedText>(); for (String splitedString : splitedStringList) { if (StringUtils.startsWithAny(splitedString, OUT_LINK_START_WITHS)) { formattedTextList.add(getFormattedText(splitedString, ' ', FormattedText.Type.OUT_LINK)); } else if (StringUtils.startsWith(splitedString, INNER_LINK_ARTICLE_START_WITH)) { formattedTextList.add( getFormattedText(splitedString, '|', FormattedText.Type.IN_LINK_ARTICLE)); } else if (StringUtils.startsWith(splitedString, INNER_LINK_PERSON_START_WITH)) { formattedTextList.add( getFormattedText(splitedString, '|', FormattedText.Type.IN_LINK_PERSON)); } else { formattedTextList.add(getPlainText(splitedString)); } } return formattedTextList; }
@Override /** * copied from org.supercsv.io.AbstractCsvWriter * * @see org.supercsv.io.AbstractCsvWriter */ protected String escapeString(String csvElement) { String escaped = super.escapeString(csvElement); if (!StringUtils.startsWith(escaped, String.valueOf((char) preference.getQuoteChar()))) { return (char) preference.getQuoteChar() + escaped + (char) preference.getQuoteChar(); } return escaped; }
private List<TaobaoCommentBean> parseTaobaoComment(String result, Task task) { JSONObject rateDetail = JSON.parseObject(result).getJSONObject("rateDetail"); JSONArray rateList = rateDetail.getJSONArray("rateList"); List<TaobaoCommentBean> beans = new ArrayList<TaobaoCommentBean>(rateList.size()); String itemId = HttpURLUtils.getUrlParams(task.getUrl(), "GBK").get("itemId"); TaobaoCommentBean bean = null; for (int i = 0; i < rateList.size(); i++) { bean = new TaobaoCommentBean(); bean.setType(task.getExtra()); bean.setItemId(itemId); try { JSONObject rate = rateList.getJSONObject(i); bean.setId(rate.getString("id")); bean.setConmment(rate.getString("rateContent")); bean.setCommentTime(rate.getString("rateDate")); bean.setReply(rate.getString("reply")); String appendCommentJson = rate.getString("appendComment"); if (!StringUtils.isBlank(appendCommentJson) && StringUtils.startsWith(appendCommentJson, "{")) { JSONObject appendComment = JSON.parseObject(appendCommentJson); bean.setAppandConmment(appendComment.getString("content")); } else { bean.setAppandConmment(appendCommentJson); } bean.setServiceComment(rate.getString("serviceRateContent")); // user bean.setNick(rate.getString("displayUserNick")); bean.setVip(rate.getString("tamllSweetLevel")); beans.add(bean); } catch (Exception e) { } } return beans; }
protected static MailAddress parsePath(int maxNumParams, String prefix, String str) throws SmtpCommandException { String[] params = parseParameters(1, maxNumParams, str); if (!StringUtils.startsWith(params[0], prefix) || !StringUtils.endsWith( params[0], ToolMailAddressUtils.MAIL_ADDR_PART_PERSONAL_ADDR_SUFFIX)) { throw new SmtpCommandException( new SmtpReplyImpl( SmtpReplyCode.SYNTAX_ERROR_ARGUMENTS, String.format( "Required syntax: '%slocal@domain%s'", prefix, ToolMailAddressUtils.MAIL_ADDR_PART_PERSONAL_ADDR_SUFFIX))); } int pathLen = (params[0] = StringUtils.removeEnd( StringUtils.removeStart(params[0], prefix), ToolMailAddressUtils.MAIL_ADDR_PART_PERSONAL_ADDR_SUFFIX)) .length(); if (pathLen > MAX_PATH_LEN) { throw new SmtpCommandException( new SmtpReplyImpl( SmtpReplyCode.SYNTAX_ERROR_ARGUMENTS, String.format("Path too long: %d > %d", pathLen, MAX_PATH_LEN))); } Matcher pathMatcher = PATTERN_PATH.matcher(params[0]); if (!pathMatcher.matches()) { throw new SmtpCommandException( new SmtpReplyImpl( SmtpReplyCode.SYNTAX_ERROR_ARGUMENTS, String.format("Malformed email address: %s", params[0]))); } return new MailAddressImpl(pathMatcher.group(1)); }
/** * 注解到对象复制,只复制能匹配上的方法。 * * @param annotation * @param object */ public static void annotationToObject(Object annotation, Object object) { if (annotation != null) { Class<?> annotationClass = annotation.getClass(); Class<?> objectClass = object.getClass(); for (Method m : objectClass.getMethods()) { if (StringUtils.startsWith(m.getName(), "set")) { try { String s = StringUtils.uncapitalize(StringUtils.substring(m.getName(), 3)); Object obj = annotationClass.getMethod(s).invoke(annotation); if (obj != null && !"".equals(obj.toString())) { if (object == null) { object = objectClass.newInstance(); } m.invoke(object, obj); } } catch (Exception e) { // 忽略所有设置失败方法 } } } } }
@Nullable private String makeAbsoluteURL(final String url) { // Check if uri is absolute or not, if not attach the connector hostname // FIXME: that should also include the scheme if (Uri.parse(url).isAbsolute()) { return url; } final String host = ConnectorFactory.getConnector(geocode).getHost(); if (StringUtils.isNotEmpty(host)) { final StringBuilder builder = new StringBuilder("http://"); builder.append(host); if (!StringUtils.startsWith(url, "/")) { // FIXME: explain why the result URL would be valid if the path does not start with // a '/', or signal an error. builder.append('/'); } builder.append(url); return builder.toString(); } return null; }
public boolean isPrefixOf(TaskCharSet other) { return StringUtils.startsWith( other.getJoinedStringOfIdentifiers(), this.getJoinedStringOfIdentifiers()); }
/** * Creates any result types from the resources available in the web application. This scans the * web application resources using the servlet context. * * @param actionClass The action class the results are being built for. * @param results The results map to put the result configs created into. * @param resultPath The calculated path to the resources. * @param resultPrefix The prefix for the result. This is usually <code>/resultPath/actionName * </code>. * @param actionName The action name which is used only for logging in this implementation. * @param packageConfig The package configuration which is passed along in order to determine * @param resultsByExtension The map of extensions to result type configuration instances. */ protected void createFromResources( Class<?> actionClass, Map<String, ResultConfig> results, final String resultPath, final String resultPrefix, final String actionName, PackageConfig packageConfig, Map<String, ResultTypeConfig> resultsByExtension) { if (LOG.isTraceEnabled()) { LOG.trace( "Searching for results in the Servlet container at [#0]" + " with result prefix of [#1]", resultPath, resultPrefix); } // Build from web application using the ServletContext @SuppressWarnings("unchecked") Set<String> paths = servletContext.getResourcePaths(flatResultLayout ? resultPath : resultPrefix); if (paths != null) { for (String path : paths) { if (LOG.isTraceEnabled()) { LOG.trace("Processing resource path [#0]", path); } String fileName = StringUtils.substringAfterLast(path, "/"); if (StringUtils.isBlank(fileName) || StringUtils.startsWith(fileName, ".")) { if (LOG.isTraceEnabled()) LOG.trace("Ignoring file without name [#0]", path); continue; } else if (fileName.lastIndexOf(".") > 0) { String suffix = fileName.substring(fileName.lastIndexOf(".") + 1); if (conventionsService.getResultTypesByExtension(packageConfig).get(suffix) == null) { if (LOG.isDebugEnabled()) LOG.debug( "No result type defined for file suffix : [#0]. Ignoring file #1", suffix, fileName); continue; } } makeResults(actionClass, path, resultPrefix, results, packageConfig, resultsByExtension); } } // Building from the classpath String classPathLocation = resultPath.startsWith("/") ? resultPath.substring(1, resultPath.length()) : resultPath; if (LOG.isTraceEnabled()) { LOG.trace( "Searching for results in the class path at [#0]" + " with a result prefix of [#1] and action name [#2]", classPathLocation, resultPrefix, actionName); } ResourceFinder finder = new ResourceFinder(classPathLocation, getClassLoaderInterface()); try { Map<String, URL> matches = finder.getResourcesMap(""); if (matches != null) { Test<URL> resourceTest = getResourceTest(resultPath, actionName); for (Map.Entry<String, URL> entry : matches.entrySet()) { if (resourceTest.test(entry.getValue())) { if (LOG.isTraceEnabled()) { LOG.trace("Processing URL [#0]", entry.getKey()); } String urlStr = entry.getValue().toString(); int index = urlStr.lastIndexOf(resultPrefix); String path = urlStr.substring(index); makeResults( actionClass, path, resultPrefix, results, packageConfig, resultsByExtension); } } } } catch (IOException ex) { if (LOG.isErrorEnabled()) LOG.error("Unable to scan directory [#0] for results", ex, classPathLocation); } }
protected void processRequest(final HttpServletRequest req, final HttpServletResponse resp) { LanternUtils.addCSPHeader(resp); final String uri = req.getRequestURI(); log.debug("Received URI: {}", uri); final String interactionStr = StringUtils.substringAfterLast(uri, "/"); if (StringUtils.isBlank(interactionStr)) { log.debug("blank interaction"); HttpUtils.sendClientError(resp, "blank interaction"); return; } log.debug("Headers: " + HttpUtils.getRequestHeaders(req)); if (!"XMLHttpRequest".equals(req.getHeader("X-Requested-With"))) { log.debug("invalid X-Requested-With"); HttpUtils.sendClientError(resp, "invalid X-Requested-With"); return; } if (!SecurityUtils.constantTimeEquals(model.getXsrfToken(), req.getHeader("X-XSRF-TOKEN"))) { log.debug( "X-XSRF-TOKEN wrong: got {} expected {}", req.getHeader("X-XSRF-TOKEN"), model.getXsrfToken()); HttpUtils.sendClientError(resp, "invalid X-XSRF-TOKEN"); return; } final int cl = req.getContentLength(); String json = ""; if (cl > 0) { try { json = IOUtils.toString(req.getInputStream()); } catch (final IOException e) { log.error("Could not parse json?"); } } log.debug("Body: '" + json + "'"); final Interaction inter = Interaction.valueOf(interactionStr.toUpperCase()); if (inter == Interaction.CLOSE) { if (handleClose(json)) { return; } } if (inter == Interaction.URL) { final String url = JsonUtils.getValueFromJson("url", json); if (!StringUtils.startsWith(url, "http://") && !StringUtils.startsWith(url, "https://")) { log.error("http(s) url expected, got {}", url); HttpUtils.sendClientError(resp, "http(s) urls only"); return; } try { new URL(url); } catch (MalformedURLException e) { log.error("invalid url: {}", url); HttpUtils.sendClientError(resp, "invalid url"); return; } final String cmd; if (SystemUtils.IS_OS_MAC_OSX) { cmd = "open"; } else if (SystemUtils.IS_OS_LINUX) { cmd = "gnome-open"; } else if (SystemUtils.IS_OS_WINDOWS) { cmd = "start"; } else { log.error("unsupported OS"); HttpUtils.sendClientError(resp, "unsupported OS"); return; } try { if (SystemUtils.IS_OS_WINDOWS) { // On Windows, we have to quote the url to allow for // e.g. ? and & characters in query string params. // To quote the url, we supply a dummy first argument, // since otherwise start treats the first argument as a // title for the new console window when it's quoted. LanternUtils.runCommand(cmd, "\"\"", "\"" + url + "\""); } else { // on OS X and Linux, special characters in the url make // it through this call without our having to quote them. LanternUtils.runCommand(cmd, url); } } catch (IOException e) { log.error("open url failed"); HttpUtils.sendClientError(resp, "open url failed"); return; } return; } final Modal modal = this.model.getModal(); log.debug( "processRequest: modal = {}, inter = {}, mode = {}", modal, inter, this.model.getSettings().getMode()); if (handleExceptionalInteractions(modal, inter, json)) { return; } Modal switchTo = null; try { // XXX a map would make this more robust switchTo = Modal.valueOf(interactionStr); } catch (IllegalArgumentException e) { } if (switchTo != null && switchModals.contains(switchTo)) { if (!switchTo.equals(modal)) { if (!switchModals.contains(modal)) { this.internalState.setLastModal(modal); } Events.syncModal(model, switchTo); } return; } switch (modal) { case welcome: this.model.getSettings().setMode(Mode.unknown); switch (inter) { case GET: log.debug("Setting get mode"); handleSetModeWelcome(Mode.get); break; case GIVE: log.debug("Setting give mode"); handleSetModeWelcome(Mode.give); break; } break; case authorize: log.debug("Processing authorize modal..."); this.internalState.setModalCompleted(Modal.authorize); this.internalState.advanceModal(null); break; case finished: this.internalState.setCompletedTo(Modal.finished); switch (inter) { case CONTINUE: log.debug("Processing continue"); this.model.setShowVis(true); Events.sync(SyncPath.SHOWVIS, true); this.internalState.setModalCompleted(Modal.finished); this.internalState.advanceModal(null); break; case SET: log.debug("Processing set in finished modal...applying JSON\n{}", json); applyJson(json); break; default: log.error("Did not handle interaction {} for modal {}", inter, modal); HttpUtils.sendClientError( resp, "Interaction not handled for modal: " + modal + " and interaction: " + inter); break; } break; case firstInviteReceived: log.error("Processing invite received..."); break; case lanternFriends: this.internalState.setCompletedTo(Modal.lanternFriends); switch (inter) { case FRIEND: this.friender.addFriend(email(json)); break; case REJECT: this.friender.removeFriend(email(json)); break; case CONTINUE: // This dialog always passes continue as of this writing and // not close. case CLOSE: log.debug("Processing continue/close for friends dialog"); if (this.model.isSetupComplete()) { Events.syncModal(model, Modal.none); } else { this.internalState.setModalCompleted(Modal.lanternFriends); this.internalState.advanceModal(null); } break; default: log.error("Did not handle interaction {} for modal {}", inter, modal); HttpUtils.sendClientError( resp, "Interaction not handled for modal: " + modal + " and interaction: " + inter); break; } break; case none: break; case notInvited: switch (inter) { case RETRY: Events.syncModal(model, Modal.authorize); break; // not currently implemented: // case REQUESTINVITE: // Events.syncModal(model, Modal.requestInvite); // break; default: log.error("Unexpected interaction: " + inter); break; } break; case proxiedSites: this.internalState.setCompletedTo(Modal.proxiedSites); switch (inter) { case CONTINUE: if (this.model.isSetupComplete()) { Events.syncModal(model, Modal.none); } else { this.internalState.setModalCompleted(Modal.proxiedSites); this.internalState.advanceModal(null); } break; case LANTERNFRIENDS: log.debug("Processing lanternFriends from proxiedSites"); Events.syncModal(model, Modal.lanternFriends); break; case SET: if (!model.getSettings().isSystemProxy()) { String msg = "Because you are using manual proxy " + "configuration, you may have to restart your " + "browser for your updated proxied sites list " + "to take effect."; model.addNotification(msg, MessageType.info, 30); Events.sync(SyncPath.NOTIFICATIONS, model.getNotifications()); } applyJson(json); break; case SETTINGS: log.debug("Processing settings from proxiedSites"); Events.syncModal(model, Modal.settings); break; default: log.error("Did not handle interaction {} for modal {}", inter, modal); HttpUtils.sendClientError(resp, "unexpected interaction for proxied sites"); break; } break; case requestInvite: log.info("Processing request invite"); switch (inter) { case CANCEL: this.internalState.setModalCompleted(Modal.requestInvite); this.internalState.advanceModal(Modal.notInvited); break; case CONTINUE: applyJson(json); this.internalState.setModalCompleted(Modal.proxiedSites); // TODO: need to do something here this.internalState.advanceModal(null); break; default: log.error("Did not handle interaction {} for modal {}", inter, modal); HttpUtils.sendClientError(resp, "unexpected interaction for request invite"); break; } break; case requestSent: log.debug("Process request sent"); break; case settings: switch (inter) { case GET: log.debug("Setting get mode"); // Only deal with a mode change if the mode has changed! if (modelService.getMode() == Mode.give) { // Break this out because it's set in the subsequent // setMode call final boolean everGet = model.isEverGetMode(); this.modelService.setMode(Mode.get); if (!everGet) { // need to do more setup to switch to get mode from // give mode model.setSetupComplete(false); model.setModal(Modal.proxiedSites); Events.syncModel(model); } else { // This primarily just triggers a setup complete event, // which triggers connecting to proxies, setting up // the local system proxy, etc. model.setSetupComplete(true); } } break; case GIVE: log.debug("Setting give mode"); this.modelService.setMode(Mode.give); break; case CLOSE: log.debug("Processing settings close"); Events.syncModal(model, Modal.none); break; case SET: log.debug("Processing set in setting...applying JSON\n{}", json); applyJson(json); break; case RESET: log.debug("Processing reset"); Events.syncModal(model, Modal.confirmReset); break; case PROXIEDSITES: log.debug("Processing proxied sites in settings"); Events.syncModal(model, Modal.proxiedSites); break; case LANTERNFRIENDS: log.debug("Processing friends in settings"); Events.syncModal(model, Modal.lanternFriends); break; default: log.error("Did not handle interaction {} for modal {}", inter, modal); HttpUtils.sendClientError( resp, "Interaction not handled for modal: " + modal + " and interaction: " + inter); break; } break; case settingsLoadFailure: switch (inter) { case RETRY: modelIo.reload(); Events.sync(SyncPath.NOTIFICATIONS, model.getNotifications()); Events.syncModal(model, model.getModal()); break; case RESET: backupSettings(); Events.syncModal(model, Modal.welcome); break; default: log.error("Did not handle interaction {} for modal {}", inter, modal); break; } break; case systemProxy: this.internalState.setCompletedTo(Modal.systemProxy); switch (inter) { case CONTINUE: log.debug("Processing continue in systemProxy", json); applyJson(json); Events.sync(SyncPath.SYSTEMPROXY, model.getSettings().isSystemProxy()); this.internalState.setModalCompleted(Modal.systemProxy); this.internalState.advanceModal(null); break; default: log.error("Did not handle interaction {} for modal {}", inter, modal); HttpUtils.sendClientError(resp, "error setting system proxy pref"); break; } break; case updateAvailable: switch (inter) { case CLOSE: this.internalState.setModalCompleted(Modal.updateAvailable); this.internalState.advanceModal(null); break; default: log.error("Did not handle interaction {} for modal {}", inter, modal); break; } break; case authorizeLater: log.error("Did not handle interaction {} for modal {}", inter, modal); break; case confirmReset: log.debug("Handling confirm reset interaction"); switch (inter) { case CANCEL: log.debug("Processing cancel"); Events.syncModal(model, Modal.settings); break; case RESET: handleReset(); Events.syncModel(this.model); break; default: log.error("Did not handle interaction {} for modal {}", inter, modal); HttpUtils.sendClientError( resp, "Interaction not handled for modal: " + modal + " and interaction: " + inter); } break; case about: // fall through on purpose case sponsor: switch (inter) { case CLOSE: Events.syncModal(model, this.internalState.getLastModal()); break; default: HttpUtils.sendClientError(resp, "invalid interaction " + inter); } break; case contact: switch (inter) { case CONTINUE: String msg; MessageType messageType; try { lanternFeedback.submit(json, this.model.getProfile().getEmail()); msg = "Thank you for contacting Lantern."; messageType = MessageType.info; } catch (Exception e) { log.error("Error submitting contact form: {}", e); msg = "Error sending message. Please check your " + "connection and try again."; messageType = MessageType.error; } model.addNotification(msg, messageType, 30); Events.sync(SyncPath.NOTIFICATIONS, model.getNotifications()); // fall through because this should be done in both cases: case CANCEL: Events.syncModal(model, this.internalState.getLastModal()); break; default: HttpUtils.sendClientError(resp, "invalid interaction " + inter); } break; case giveModeForbidden: if (inter == Interaction.CONTINUE) { // need to do more setup to switch to get mode from give mode model.getSettings().setMode(Mode.get); model.setSetupComplete(false); this.internalState.advanceModal(null); Events.syncModal(model, Modal.proxiedSites); Events.sync(SyncPath.SETUPCOMPLETE, false); } break; default: log.error("No matching modal for {}", modal); } this.modelIo.write(); }