/** Searches for objects to return based on the filter provided with offset and limit features. */
  public void executeQuery(
      ObjectClass oclass, String query, ResultsHandler handler, OperationOptions options) {
    /** Track the number of lines processed. */
    long lines = 0;

    /** Text qualifier character. */
    final char textQualifier = cfg.getTextQualifier();

    /** Field delimiter. */
    final char fieldSeparator = cfg.getFieldDelimiter();

    /** Unique identifier field. */
    final String uniqueIdField = cfg.getUniqueAttributeName();

    /** Internal reader initialized in the constructor. */
    BufferedReader rdr = null;

    try {
      rdr = cfg.newFileReader();
      /** Fields names read from the header. */
      List<String> fieldNames =
          FlatFileConnector.readHeader(rdr, fieldSeparator, textQualifier, uniqueIdField);

      String line;
      while ((line = rdr.readLine()) != null) {
        ++lines;
        if (line.trim().length() == 0) {
          LOG.info(MSG_SKIPPING);
          continue;
        }
        LOG.ok("Processing Data Line: {0}", line);
        List<String> fieldValues = StringUtil.parseLine(line, fieldSeparator, textQualifier);
        if (fieldValues == null) {
          LOG.error("Error: {0}", line);
          break;
        } else {
          ConnectorObjectBuilder bld = new ConnectorObjectBuilder();
          for (int i = 0; i < fieldValues.size(); ++i) {
            String name = fieldNames.get(i);
            String value = fieldValues.get(i);
            if (name.equals(uniqueIdField)) {
              bld.setUid(value);
              bld.setName(value);
            } else {
              bld.addAttribute(name, value);
            }
          }
          // create the connector object..
          ConnectorObject ret = bld.build();
          if (!handler.handle(ret)) {
            break;
          }
        }
      }
    } catch (IOException e) {
      throw new ConnectorIOException(e);
    } finally {
      IOUtil.quietClose(rdr);
    }
  }
 /**
  * Read the header from the file and determine the attributes for the account object this resource
  * supports.
  */
 public Schema schema() {
   // read the header to construct an ConnectionObjectInfo..
   final SchemaBuilder bld = new SchemaBuilder(getClass());
   BufferedReader rdr = null;
   try {
     // open the file for reading..
     rdr = this.cfg.newFileReader();
     // build the connector info object..
     // read the header..
     Set<AttributeInfo> attrInfos = new HashSet<AttributeInfo>();
     List<String> fieldNames =
         readHeader(
             rdr,
             this.cfg.getFieldDelimiter(),
             this.cfg.getTextQualifier(),
             this.cfg.getUniqueAttributeName());
     for (String fieldName : fieldNames) {
       AttributeInfoBuilder abld = new AttributeInfoBuilder();
       abld.setName(fieldName);
       abld.setCreateable(false);
       abld.setUpdateable(false);
       attrInfos.add(abld.build());
     }
     // set it to object class account..
     bld.defineObjectClass(ObjectClass.ACCOUNT_NAME, attrInfos);
   } catch (IOException e) {
     throw new IllegalStateException(e);
   } finally {
     IOUtil.quietClose(rdr);
   }
   // return the new schema object..
   return bld.build();
 }