protected void addJSFile(TernDoc doc, ITernFile file) throws IOException {
   TernQuery query = doc.getQuery();
   String fileName = file.getFullName(getProject());
   query.setFile(fileName);
   TernFile tf = file.toTernServerFile(getProject());
   doc.addFile(tf);
 }
  private TernDoc createDocForCompletionModuleCheckFiles() {
    TernDoc doc = new TernDoc();

    TernAngularCompletionsQuery query = new TernAngularCompletionsQuery(AngularType.module);
    query.setExpression("");

    doc.setQuery(query);
    return doc;
  }
  @Test
  public void todoTextAfterEnd() throws TernException {

    TernDoc doc = createDocForDefinitionTodoText();
    doc.getQuery().setEnd(9);

    MockTernDefinitionCollector collector = new MockTernDefinitionCollector();
    server.request(doc, collector);

    Assert.assertNull(collector.getFile());
  }
  private TernDoc createDocForDefinitionTodoText() {
    TernDoc doc = createFile();

    TernAngularDefinitionQuery query = new TernAngularDefinitionQuery(AngularType.model);
    query.addFile("myfile.js");
    query.getScope().getControllers().add("TodoCtrl");
    query.setExpression("todoText");

    doc.setQuery(query);
    return doc;
  }
  private TernDoc createDocForDefinitionWithModule() {
    TernDoc doc = createFileWithModule();

    TernAngularDefinitionQuery query = new TernAngularDefinitionQuery(AngularType.model);
    query.addFile("myfile.js");
    query.getScope().setModule("MyApp");
    query.getScope().getControllers().add("SomeCtrl");
    query.setExpression("save");
    query.setEnd(1);
    doc.setQuery(query);
    return doc;
  }
  private TernDoc createFileWithModule() {
    String name = "myfile.js";
    String text =
        "angular.module('MyApp', [])"
            + "\n.controller('SomeCtrl', function($scope, $http) {"
            + "\n$scope.save = function() {};"
            + "\n$http. // <-- you'll have completions now"
            + "\n});";

    TernDoc doc = new TernDoc();
    doc.addFile(name, text, null, null);
    return doc;
  }
  private TernDoc createDocForCompletionModuleStartsWith() {
    String name = "myfile.js";
    String text = "angular.module('phonecatApp');" + "angular.module('phonecatAnimations');";

    TernDoc doc = new TernDoc();
    doc.addFile(name, text, null, null);

    TernAngularCompletionsQuery query = new TernAngularCompletionsQuery(AngularType.module);
    query.setExpression("phonecatAn");

    doc.setQuery(query);
    return doc;
  }
 @Override
 public void request(TernDoc doc) {
   if (doc.hasFiles()) {
     synchronized (files) {
       for (JsonValue val : doc.getFiles().values()) {
         if (val instanceof TernFile) {
           TernFile file = (TernFile) val;
           files.remove(file.getName());
           files.put(file.getName(), file);
         }
       }
       schedule();
     }
   }
 }
  @Test
  public void todoTextDefinedInScopeToo() throws TernException {

    TernDoc doc = createDocForDefinitionTodoText();
    ((TernAngularDefinitionQuery) doc.getQuery()).getScope().getProps().add("todoText", "todoText");
    MockTernDefinitionCollector collector = new MockTernDefinitionCollector();
    server.request(doc, collector);

    Assert.assertNotNull(collector.getFile());
    Assert.assertEquals("myfile.js", collector.getFile());
    Assert.assertNotNull(collector.getStart());
    Assert.assertEquals(216, collector.getStart().longValue());
    Assert.assertNotNull(collector.getEnd());
    Assert.assertEquals(224, collector.getEnd().longValue());
  }
  @Test
  public void todoTextBeforeEnd() throws TernException {

    TernDoc doc = createDocForDefinitionTodoText();
    doc.getQuery().setEnd(8);

    MockTernDefinitionCollector collector = new MockTernDefinitionCollector();
    server.request(doc, collector);

    Assert.assertNotNull(collector.getFile());
    Assert.assertEquals("myfile.js", collector.getFile());
    Assert.assertNotNull(collector.getStart());
    Assert.assertEquals(216, collector.getStart().longValue());
    Assert.assertNotNull(collector.getEnd());
    Assert.assertEquals(224, collector.getEnd().longValue());
  }
 protected void sendFiles(TernDoc doc) {
   if (doc.hasFiles()) {
     updateSentFiles(doc);
     // sync is performed asynchronously
     uploader.request(doc);
   }
 }
 @Override
 public void synchronizeFile(ITernFile file) throws IOException {
   writeLock.lock();
   try {
     TernFile tf = file.toTernServerFile(getProject());
     String oldText = sentFiles.get(tf.getName());
     if (tf.getText().equals(oldText) && !uploader.cancel(tf.getName())) {
       // no need to synchronize the file, already up-to-date
       return;
     }
     TernDoc doc = new TernDoc();
     doc.addFile(tf);
     sendFiles(doc);
   } finally {
     writeLock.unlock();
   }
 }
  @Override
  public void synchronizeScriptPath(ITernScriptPath path, String... forced) {
    TernDoc doc = new TernDoc();
    writeLock.lock();
    try {
      // make sure we do not send duplicate files
      Set<String> requestedFiles = new HashSet<String>(sentFiles.keySet());
      Set<String> perPath = new HashSet<String>();
      syncedFilesPerPath.put(path, perPath);

      requestedFiles.removeAll(Arrays.asList(forced));

      long totalSize = 0;
      for (String file : requestedFiles) {
        totalSize += sentFiles.get(file).length();
      }

      for (ITernScriptResource resource : path.getScriptResources()) {
        // limit the number of files being sent to the Tern server
        if (totalSize >= MAX_ALLOWED_SIZE) {
          sizeExceeded();
          break;
        }
        ITernFile file = resource.getFile();
        if (file == null) {
          continue;
        }
        String name = file.getFullName(getProject());
        perPath.add(name);
        if (!requestedFiles.contains(name)) {
          try {
            TernFile tf = file.toTernServerFile(getProject());
            doc.addFile(tf);
            totalSize += tf.getText().length();
            requestedFiles.add(name);
          } catch (IOException e) {
            getProject().handleException(e);
          }
        }
      }
      // perform actual synchronization with the server
      sendFiles(doc);
    } finally {
      writeLock.unlock();
    }
  }
  private TernDoc createFile() {
    String name = "myfile.js";
    String text =
        "function TodoCtrl($scope) {\n"
            + "$scope.todos = ["
            + "\n{text:'learn angular', done:true},"
            + "\n{text:'build an angular app', done:false}];"
            + "\n$scope.addTodo = function() {"
            + "\n$scope.todos.push({text:$scope.todoText, done:false});"
            + "\n$scope.todoText = '';"
            + "\n};"
            + "\n}";

    TernDoc doc = new TernDoc();
    doc.addFile(name, text, null, null);
    return doc;
  }
 @Override
 public void uploadFailed(TernDoc doc) {
   synchronized (toRefresh) {
     for (JsonValue val : doc.getFiles()) {
       if (val instanceof TernFile) {
         toRefresh.add(((TernFile) val).getName());
       }
     }
   }
 }
  @Override
  public void process(
      TernDoc doc,
      IJSONObjectHelper jsonObjectHelper,
      Object jsonObject,
      ITernLintCollector collector) {
    if (!(jsonObject instanceof JsonObject)) {
      // TODO: support for Rhino server
      return;
    }
    JsonArray messages = (JsonArray) ((JsonObject) jsonObject).get(MESSAGES_FIELD); // $NON-NLS-1$
    if (messages != null) {
      TernLintQuery query = (TernLintQuery) doc.getQuery();
      if (query.isGroupByFiles()) {
        JsonObject filesObject = null;
        String file = null;
        for (JsonValue files : messages) {
          filesObject = (JsonObject) files;
          file = jsonObjectHelper.getText(filesObject.get(FILE_FIELD)); // $NON-NLS-1$

          try {
            collector.startLint(file);

            JsonArray messagesFile = (JsonArray) filesObject.get(MESSAGES_FIELD); // $NON-NLS-1$
            if (messagesFile != null) {
              addMessages(jsonObjectHelper, messagesFile, query, collector);
            }
          } finally {
            collector.endLint(file);
          }
        }
      } else {
        String file = doc.getQuery().getFile();
        try {
          collector.startLint(file);
          addMessages(jsonObjectHelper, messages, query, collector);
        } finally {
          collector.endLint(file);
        }
      }
    }
  }
 @Override
 public void synchronizeFile(TernDoc doc, ITernFile file) throws IOException {
   writeLock.lock();
   try {
     try {
       TernQuery query = doc.getQuery();
       if (query != null) {
         if (TernResourcesManager.isJSFile(file)) {
           addJSFile(doc, file);
           sendFiles(doc);
           return;
         } else if (TernResourcesManager.isHTMLFile(file)) {
           // This is HTML file case: never keep the file on the server
           String queryType = query.getType();
           if (TernCompletionsQuery.isQueryType(queryType)
               || TernDefinitionQuery.isQueryType(queryType)
               || query instanceof TernLintQuery) {
             addHTMLFile(doc, file);
             return;
           }
         }
       }
       TernFile tf = file.toTernServerFile(getProject());
       String oldText = sentFiles.get(tf.getName());
       if (tf.getText().equals(oldText) && !uploader.cancel(tf.getName())) {
         // no need to synchronize the file, already up-to-date
         return;
       }
       doc.addFile(tf);
     } finally {
       updateSentFiles(doc);
       // as this is
       // wait a bit for the sync to finish
       uploader.join(TIMEOUT);
     }
   } finally {
     writeLock.unlock();
   }
 }
 private void updateSentFiles(TernDoc doc) {
   for (JsonValue value : doc.getFiles()) {
     if (value instanceof TernFile) {
       TernFile file = (TernFile) value;
       if (file.isType(FileType.full)) {
         String contents = file.getText();
         if (StringUtils.isEmpty(contents)) {
           // treat file with empty contents as removed
           sentFiles.remove(file.getName());
         } else {
           sentFiles.put(file.getName(), contents);
         }
       }
     }
   }
 }
  @Override
  public void ensureSynchronized() {
    TernDoc doc = new TernDoc();
    writeLock.lock();
    try {
      if (project.getTernServer() != targetServer) {
        targetServer = project.getTernServer();
        cleanIndexedFiles();
      }
      syncedFilesPerPath.clear();

      Set<String> synced = new HashSet<String>(sentFiles.keySet());
      Set<String> toRefreshLocal = new HashSet<String>();
      synchronized (toRefresh) {
        toRefreshLocal.addAll(toRefresh);
        toRefresh.clear();
      }
      synced.removeAll(toRefreshLocal);

      long totalSize = 0;
      for (String file : synced) {
        totalSize += sentFiles.get(file).length();
      }

      for (ITernScriptPath path : getProject().getScriptPaths()) {
        Set<String> perPath = new HashSet<String>();
        syncedFilesPerPath.put(path, perPath);
        for (ITernScriptResource resource : path.getScriptResources()) {
          // limit the size of content being sent to the Tern server
          if (totalSize >= MAX_ALLOWED_SIZE) {

            sendFiles(doc);
            totalSize = 0;
            doc = new TernDoc();
          }
          ITernFile file = resource.getFile();
          if (file == null) {
            continue;
          }
          String name = file.getFullName(getProject());
          perPath.add(name);
          if (!synced.contains(name)) {
            try {
              TernFile tf = file.toTernServerFile(getProject());
              doc.addFile(tf);
              synced.add(name);
              //					System.out.println(name);
              totalSize += tf.getText().length();
            } catch (IOException e) {
              getProject().handleException(e);
            }
          }
        }
      }

      toRefreshLocal.removeAll(synced);
      for (String toRemove : toRefreshLocal) {
        doc.delFile(toRemove);
      }

      // perform actual synchronization with the server
      sendFiles(doc);
    } finally {
      writeLock.unlock();
    }
  }
  @Override
  protected IStatus run(IProgressMonitor mon) {
    SubMonitor monitor = SubMonitor.convert(mon, 100);
    final ITernServer server = project.getTernServer();
    do {
      if (mon.isCanceled()) {
        return Status.CANCEL_STATUS;
      }
      int i = 0;
      final TernDoc doc = new TernDoc();
      synchronized (files) {
        monitor.setWorkRemaining(files.size() + 1);
        Iterator<Entry<String, TernFile>> it = files.entrySet().iterator();
        while (i < MAX_FILES && it.hasNext()) {
          Entry<String, TernFile> entry = it.next();
          it.remove();
          doc.addFile(entry.getValue());
          i++;
        }
      }
      if (!doc.hasFiles()) {
        break;
      }
      if (server != null) {
        try {
          server.request(
              doc,
              new IResponseHandler() {

                @Override
                public void onSuccess(Object data, String dataAsJsonString) {}

                @Override
                public void onError(String error, Throwable t) {
                  project.handleException(new TernException(error, t));
                  // mark that files have not been uploaded correctly
                  project.getFileSynchronizer().uploadFailed(doc);
                  throw new UploadFailed();
                }

                @Override
                public boolean isDataAsJsonString() {
                  return false;
                }
              });
          monitor.worked(i);
        } catch (UploadFailed ex) {
          synchronized (files) {
            TernDoc doc2 = new TernDoc();
            for (TernFile tf : files.values()) {
              doc2.addFile(tf);
            }
            files.clear();
            project.getFileSynchronizer().uploadFailed(doc2);
            cancel();
          }
          return Status.CANCEL_STATUS;
        }
      }
    } while (!serverToBeDisposed);
    return Status.OK_STATUS;
  }
 protected void addHTMLFile(TernDoc doc, ITernFile file) throws IOException {
   TernQuery query = doc.getQuery();
   TernFile tf = file.toTernServerFile(getProject());
   doc.addFile(tf);
   query.set("file", "#" + (doc.getFiles().size() - 1)); // $NON-NLS-1$ //$NON-NLS-2$
 }