eclipse插件开发-JDT_第1页
eclipse插件开发-JDT_第2页
eclipse插件开发-JDT_第3页
eclipse插件开发-JDT_第4页
eclipse插件开发-JDT_第5页
已阅读5页,还剩76页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、JDT核心JDT 核心JDT 核心(org.eclipse.jdt.core)是用于定义 Java 核心元素和 API 的插件。在开发特定于 Java 的功能部件时,总是应该将此插件列示为先决条件。JDT 核心包使您能够访问 Java 模型对象和无外设 Java IDE 基础结构。JDT 核心包包括:  · org.eclipse.jdt.core 定义用于描述 Java 模型的类。 · piler 定义编译器基础结构的 API。 · org.eclipse.jdt.core.dom 支持可用于检查编译单元的结构直到语句级别的“抽象语法树”(AST)。

2、· org.eclipse.jdt.core.eval 支持对代码片段编辑测试窗或调试器中的代码段进行评估。 · org.eclipse.jdt.core.jdom 支持 Java“文档对象模型”(DOM),它可用于表示 Java 编译单元的结构。 · org.eclipse.jdt.core.search 支持在工作空间的 Java 模型中搜索与特定描述相匹配的 Java 元素。   · org.eclipse.jdt.core.util 提供用于处理 .class 文件和 Java 模型元素的实用程序类。 从版本 3.0 起,建议

3、不要使用 org.eclipse.jdt.core.jdom。应使用 org.eclipse.jdt.core.dom 来完成对编译单元的结构的处理。Java 模型Java 模型是用来对与创建、编辑和构建 Java 程序相关联的对象进行建模的一些类。Java 模型类是在 org.eclipse.jdt.core 中定义的。这些类实现资源的特定于 Java 的行为,并进一步将 Java 资源分解成模型元素。Java 元素包 org.eclipse.jdt.core 定义了用来对组成 Java 程序的元素建模的一些类。JDT 使用内存中的对象模型来表示 Java 程序的结构。此结构是从项目的类路径

4、派生的。模型是分层的。可以将程序的元素分解成子元素。处理 Java 元素与处理资源对象相似。当使用 Java 元素时,实际上是在使用某些底层的模型对象的句柄。必须使用 exists() 协议来确定元素是否真正存在于工作空间中。 下表总结了不同种类的 Java 元素。元素描述IJavaModel表示根 Java 元素,对应于工作空间。所有具有 Java 性质的项目的父代。它还允许访问不具有 java 性质的项目。IJavaProject表示工作空间中的 Java 项目。(IJavaModel 的子代)IPackageFragmentRoot表示一组包段,并将各段映射至底层资源,它可以是

5、文件夹、JAR 或 ZIP 文件。(IJavaProject 的子代)IPackageFragment表示工作空间中的一个部分,对应于整个包或者包的一部分。(IPackageFragmentRoot 的子代)ICompilationUnit表示 Java 源(.java)文件。(IPackageFragment 的子代)IPackageDeclaration表示编译单元中的软件包声明。(ICompilationUnit 的子代)IImportContainer表示编译单元中的包导入声明的集合。(ICompilationUnit 的子代)IImportDeclaration表示单个包导入声明。(

6、IImportContainer 的子代)IType表示编译单元内的源类型,或者是类文件中的二进制类型。IField表示类型中的字段。(IType 的子代)IMethod表示类型中的方法或构造函数。(IType 的子代)IInitializer表示类型中的静态或实例初始化方法。(IType 的子代)IClassFile表示已编译(二进制)类型。(IPackageFragment 的子代)ITypeParameter 表示类型参数。(不是任何 Java 元素的子元素,可使用 IType.getTypeParameter(String) 或 IMethod.getTypeParameter(Str

7、ing) 获得)ILocalVariable 表示方法或初始化方法中的局部变量。(不是任何 Java 元素的子元素,可使用 ICodeAssist.codeSelect(int, int) 获得)所有 Java 元素都支持 IJavaElement 接口。某些元素显示在“包”视图中。这些元素实现 IOpenable 接口,原因是必须在打开它们之后才能浏览它们。下图说明这些元素在“包”视图中是如何表示的。实现 IOpenable 的 Java 元素基本上是根据在底层资源文件中找到的信息创建的。相同的元素是在资源导航器视图中按类别表示的。   其他元素对应于组成 Java 编译单元的项。

8、下图显示 Java 编译单元和内容大纲窗口(它显示编译单元中的源元素)。 因为这些元素可以提供相应的源代码,所以它们实现了 ISourceReference 接口。(当在内容大纲窗口中选择了这些元素时,就会在 Java 编辑器中显示它们相应的源代码)。Java 元素及其资源许多 Java 元素对应于工作空间中的通用资源。当您想根据通用资源来创建 Java 元素时,最好是从类 JavaCore 开始。以下代码段说明如何从 Java 元素的相应资源中获取 Java 元素。 private void createJavaElementsFrom(IProject myProject, IFolder

9、 myFolder, IFile myFile) IJavaProject myJavaProject = JavaCore.create(myProject); if (myJavaProject = null) / the project is not configured for Java (has no Java nature) return; / get a package fragment or package fragment root IJavaElement myPackageFragment = JavaCore.create(myFolder); / get a .jav

10、a (compilation unit), .class (class file), or / .jar (package fragment root) IJavaElement myJavaFile = JavaCore.create(myFile); 一旦有了 Java 元素,就可以使用 JDT API 来遍历和查询模型。还可以查询包含在 Java 元素内的非 Java 资源。    private void createJavaElementsFrom(IProject myProject, IFolder myFolder, IFile myFile) . / ge

11、t the non Java resources contained in my project. Object nonJavaChildren = myJavaProject.getNonJavaResources(); . Java 项目当根据简单项目来创建 Java 项目时,JavaCore 将检查项目是否是用 Java 性质来配置的。JDT 插件使用项目性质来将项目指定为具有 Java 行为。当“新建 Java 项目”向导创建项目时,将为项目指定此性质(org.eclipse.jdt.core.JavaCore#NATURE_ID)。如果未对项目配置 Java 性质,则在要求创建项目时

12、,JavaCore 将返回 null。JavaCore 还用来维护 Java 类路径,包括用于查找源代码和库的位置以及用于生成输出二进制(.class)文件的位置。什么是 Java 项目的唯一特征?Java 项目将它们的类路径记录在“.classpath”文件中,并将 Java 增量项目构建器添加到项目的构建规范中。否则,它们只是常规项目,并且可以由插件利用其他性质(和其他增量构建器)来配置。对于那些想要利用除了它们自己的行为之外的 Java 行为来配置项目的插件,它们通常使用 NewJavaProjectWizardPage 来为项目指定除了它们自己的定制性质或行为之外的 Java 性质。I

13、JavaModel 可以认为是工作空间中具有 Java 项目性质的所有项目的父代(因此,可以当作 IJavaProject)。处理 Java 代码插件可以使用 JDT API 来创建类或接口、将方法添加到现有类型中或者改变方法的类型。改变 Java 对象最简单的方法就是使用 Java 元素 API。可以使用更常见的技术来处理 Java 元素的初始源代码。使用 Java 元素来修改代码生成编译单元 通过程序来生成编译单元最简单的方法是使用 IPackageFragment.createCompilationUnit。指定编译单元的名称和内容。于是在包中创建了编译单元,并返回新的 ICompila

14、tionUnit。通常,可以通过在对应包目录的相应文件夹中创建扩展名为“.java”的文件资源来按类别创建编译单元。使用类属资源 API 对于 Java 工具是一种旁门左道,因此,在通知类属资源更改侦听器以及 JDT 侦听器将 Java 模型更新为新编译单元之前,Java 模型不会更新。修改编译单元 大部分对 Java 源代码的简单修改可以使用 Java 元素 API 来完成。例如,可以通过编译单元查询类型。一旦您具有 IType,就可以使用诸如 createField、createInitializer、createMethod 或 createType 的协议来将源代码成员添加至类型。在这

15、些方法中提供了源代码以及关于成员的位置的信息。ISourceManipulation 接口定义 Java 元素的常见源代码处理。这包括用于重命名、移动、复制或删除类型的成员的方法。工作副本 可以通过处理编译单元来修改代码(于是修改了底层 IFile)或人们可以修改编译单元的内存副本(称为工作副本)。工作副本是使用 getWorkingCopy 方法从编译单元中获取的。(注意,要创建工作副本,编译单元不需要存在于 Java 模型中。)当不再需要这种工作副本时,创建这种工作副本的人员应负责使用 discardWorkingCopy 方法来废弃它。工作副本修改内存缓冲区。getWorkingCopy

16、() 方法创建缺省缓冲区,但是客户机可以使用 getWorkingCopy(WorkingCopyOwner, IProblemRequestor, IProgressMonitor) 方法提供它们自己的缓冲区实现。客户机可以直接处理此缓冲区的文本。如果客户机直接处理文本,则它们必须经常使用 reconcile(int, boolean, WorkingCopyOwner, IProgressMonitor) 方法来使工作副本与缓冲区同步。最后,可以使用 commitWorkingCopy 方法将工作副本保存至磁盘(用来替换原始的编译单元)。   例如,下列代码段使用定制工

17、作副本拥有者在编译单元上创建工作副本。该代码段将修改缓冲区、协调更改、将更改落实到磁盘,最后废弃工作副本。 / Get original compilation unit ICompilationUnit originalUnit = .; / Get working copy owner WorkingCopyOwner owner = .; / Create working copy ICompilationUnit workingCopy = originalUnit.getWorkingCopy(owner, null, null); / Modify buffer and recon

18、cile IBuffer buffer = (IOpenable)workingCopy).getBuffer(); buffer.append("class X "); workingCopy.reconcile(NO_AST, false, null, null); / Commit changes workingCmitWorkingCopy(false, null); / Destroy working copy workingCopy.discardWorkingCopy();工作副本还可以供若干使用工作副本拥有者的客户机共享。稍后可以使用 findWorking

19、Copy 方法来检索工作副本。因此,对于原始编译单元和工作副本拥有者,共享工作副本很重要。下列内容说明了客户机 1 如何创建共享的工作副本、客户机 2 如何检索此工作副本、客户机 1 如何废弃此工作副本以及尝试检索共享的工作副本的客户机 2 如何注意到该工作副本不再存在: / Client 1 & 2: Get original compilation unit ICompilationUnit originalUnit = .; / Client 1 & 2: Get working copy owner WorkingCopyOwner owner = .; / Clien

20、t 1: Create shared working copy ICompilationUnit workingCopyForClient1 = originalUnit.getWorkingCopy(owner, null, null); / Client 2: Retrieve shared working copy ICompilationUnit workingCopyForClient2 = originalUnit.findWorkingCopy(owner); / This is the same working copy assert workingCopyForClient1

21、 = workingCopyForClient2; / Client 1: Discard shared working copy workingCopyForClient1.discardWorkingCopy(); / Client 2: Attempt to retrieve shared working copy and find out it's null workingCopyForClient2 = originalUnit.findWorkingCopy(owner); assert workingCopyForClient2 = null;使用 DOM/AST API

22、 来修改代码有三种方法来创建 CompilationUnit。第一种方法是使用 ASTParser。第二种方法是使用 ICompilationUnit#reconcile(.)。第三种方法是从头开始对 AST(抽象语法树)使用工厂方法。 从现有的源代码创建 AST必须使用 ASTParser.newParser(int) 来创建 ASTParser 的实例。将使用下列其中一个方法将源代码提供给 ASTParser: · setSource(char):从源代码创建 AST · setSource(IClassFile):从类文件创建 AST · setSource

23、(ICompilationUnit):从编译单元创建 AST 然后通过调用 createAST(IProgressMonitor) 来创建 AST。结果是每个节点都有一个具有正确源位置的 AST。在使用 setResolveBindings(boolean) 创建树之前,必须请求绑定的解决方案。解决绑定是一个成本很高的操作,仅当需要时才执行。一旦修改了树,就会丢失所有位置和绑定。 通过协调工作副本来创建 AST 如果工作副本不一致(已修改),则可以通过调用方法 reconcile(int, boolean, org.eclipse.jdt.core.WorkingCopyOwner, org.

24、eclipse.core.runtime.IProgressMonitor) 来创建 AST。要请求 AST 创建,使用 AST.JLS2 作为第一个参数来调用 reconcile(.) 方法。仅当问题请求程序是活动或者当强制执行问题检测时,才会计算其绑定。解决绑定是一个成本很高的操作,仅当需要时才执行。一旦修改了树,就会丢失所有位置和绑定。 从头开始 可以通过对 AST 使用工厂方法来从头创建 CompilationUnit。这些方法名以 new. 开头。以下是创建 HelloWorld 类的一个示例。第一个代码段是生成的输出: package example; import java.ut

25、il.*; public class HelloWorld public static void main(String args) System.out.println("Hello" + " world");下列代码段是生成输出的相应代码。 AST ast = new AST();CompilationUnit unit = ast.newCompilationUnit();PackageDeclaration packageDeclaration = ast.newPackageDeclaration();packageDeclaration.se

26、tName(ast.newSimpleName("example");unit.setPackage(packageDeclaration);ImportDeclaration importDeclaration = ast.newImportDeclaration();QualifiedName name =ast.newQualifiedName(ast.newSimpleName("java"),ast.newSimpleName("util");importDeclaration.setName(name);importDec

27、laration.setOnDemand(true);unit.imports().add(importDeclaration);TypeDeclaration type = ast.newTypeDeclaration();type.setInterface(false);type.setModifiers(Modifier.PUBLIC);type.setName(ast.newSimpleName("HelloWorld");MethodDeclaration methodDeclaration = ast.newMethodDeclaration();methodD

28、eclaration.setConstructor(false);methodDeclaration.setModifiers(Modifier.PUBLIC | Modifier.STATIC);methodDeclaration.setName(ast.newSimpleName("main");methodDeclaration.setReturnType(ast.newPrimitiveType(PrimitiveType.VOID);SingleVariableDeclaration variableDeclaration = ast.newSingleVaria

29、bleDeclaration();variableDeclaration.setModifiers(Modifier.NONE);variableDeclaration.setType(ast.newArrayType(ast.newSimpleType(ast.newSimpleName("String");variableDeclaration.setName(ast.newSimpleName("args");methodDeclaration.parameters().add(variableDeclaration);org.eclipse.jd

30、t.core.dom.Block block = ast.newBlock();MethodInvocation methodInvocation = ast.newMethodInvocation();name = ast.newQualifiedName(ast.newSimpleName("System"),ast.newSimpleName("out");methodInvocation.setExpression(name);methodInvocation.setName(ast.newSimpleName("println&quo

31、t;);InfixExpression infixExpression = ast.newInfixExpression();infixExpression.setOperator(InfixExpression.Operator.PLUS);StringLiteral literal = ast.newStringLiteral();literal.setLiteralValue("Hello");infixExpression.setLeftOperand(literal);literal = ast.newStringLiteral();literal.setLite

32、ralValue(" world");infixExpression.setRightOperand(literal);methodInvocation.arguments().add(infixExpression);ExpressionStatement expressionStatement = ast.newExpressionStatement(methodInvocation);block.statements().add(expressionStatement);methodDeclaration.setBody(block);type.bodyDeclara

33、tions().add(methodDeclaration);unit.types().add(type);检索额外的位置DOM/AST 节点只包含一对位置(起始位置和节点的长度)。这并不总是够用。要检索中间位置,应使用 IScanner API。例如,我们具有想要对其了解 instanceof 运算符的位置的 InstanceofExpression。可以编写以下方法来实现此目的: private int getOperatorPosition(Expression expression, char source) if (expression instanceof InstanceofEx

34、pression) IScanner scanner = ToolFactory.createScanner(false, false, false, false);scanner.setSource(source);int start = expression.getStartPosition();int end = start + expression.getLength();scanner.resetTo(start, end);int token;try while (token = scanner.getNextToken() != ITerminalSymbols.TokenNam

35、eEOF) switch(token) case ITerminalSymbols.TokenNameinstanceof:return new int scanner.getCurrentTokenStartPosition(), scanner.getCurrentTokenEndPosition(); catch (InvalidInputException e) return null;IScanner 用来将输入源代码分成多个标记。每个标记都具有特定值,这些特定值是在 ITerminalSymbols 接口中定义的。迭代和检索正确的标记是非常简单的。如果想要在 SuperMethod

36、Invocation 中查找 super 关键字的位置,则还建议您使用扫描程序。 源代码修改某些源代码修改不是通过 Java 元素 API 来提供的。编辑源代码(例如,更改现有元素的源代码)的较常见方法是使用编译单元的初始源代码和 DOM/AST 的重写 API 来完成的。要执行 DOM/AST 重写,存在两组 API:描述性重写和修改重写。 描述性 API 不修改 AST,而是使用 ASTRewrite API 来生成修改描述。AST 重写程序收集对节点修改的描述并将这些描述转换为可以适用于初始源代码的文本编辑。 / creation of a Document ICompilationUn

37、it cu = . ; / content is "public class X n" String source = cu.getBuffer().getContents(); Document document= new Document(source); / creation of DOM/AST from a ICompilationUnit ASTParser parser = ASTParser.newParser(AST.JLS2); parser.setSource(cu); CompilationUnit astRoot = (CompilationUni

38、t) parser.createAST(null); / creation of ASTRewrite ASTRewrite rewrite = new ASTRewrite(astRoot.getAST(); / description of the change SimpleName oldName = (TypeDeclaration)astRoot.types().get(0).getName(); SimpleName newName = astRoot.getAST().newSimpleName("Y"); rewrite.replace(oldName, n

39、ewName, null); / computation of the text edits TextEdit edits = rewrite.rewriteAST(document, cu.getJavaProject().getOptions(true); / computation of the new source code edits.apply(document); String newSource = document.get(); / update of the compilation unit cu.getBuffer().setContents(newSource);修改

40、API 允许直接修改 AST: · 请求记录修改(CompilationUnit.recordModifications())。 · 对 AST 节点执行修改。 · 当完成修改时,生成可以适用于初始源代码的文本编辑(CompilationUnit.rewrite(.))。 / creation of a Document ICompilationUnit cu = . ; / content is "public class X n" String source = cu.getBuffer().getContents(); Document

41、document= new Document(source); / creation of DOM/AST from a ICompilationUnit ASTParser parser = ASTParser.newParser(AST.JLS2); parser.setSource(cu); CompilationUnit astRoot = (CompilationUnit) parser.createAST(null); / start record of the modifications astRoot.recordModifications(); / modify the AS

42、T TypeDeclaration typeDeclaration = (TypeDeclaration)astRoot.types().get(0) SimpleName newName = astRoot.getAST().newSimpleName("Y"); typeDeclaration.setName(newName); / computation of the text edits TextEdit edits = astRoot.rewrite(document, cu.getJavaProject().getOptions(true); / computa

43、tion of the new source code edits.apply(document); String newSource = document.get(); / update of the compilation unit cu.getBuffer().setContents(newSource);对 Java 元素的更改作出响应如果事后插件需要知道对 Java 元素所作的更改,则可以向 JavaCore 注册 Java IElementChangedListener。 JavaCore.addElementChangedListener(new MyJavaElementCha

44、ngeReporter();还可以更具体,并使用 addElementChangedListener(IElementChangedListener, int) 来指定您感兴趣的事件的类型。例如,如果您只想在协调操作期间侦听事件: JavaCore.addElementChangedListener(new MyJavaElementChangeReporter(), ElementChangedEvent.POST_RECONCILE);JavaCore 支持二种类型的事件: · POST_CHANGE:在相应的 POST_CHANGE 资源更改通知期间,将通知此事件类型的侦听器。

45、 · POST_RECONCILE:在结束对工作副本的协调操作时,将通知此事件类型的侦听器(请参阅 ICompilationUnit.reconcile(int, boolean, WorkingCopyOwner, IProgressMonitor))。 Java 元素更改侦听器在概念上类似于资源更改侦听器(在跟踪资源更改中进行了描述)。下列代码段实现 Java 元素更改指示器,它将元素变化打印到系统控制台中。public class MyJavaElementChangeReporter implements IElementChangedListener public void

46、 elementChanged(ElementChangedEvent event) IJavaElementDelta delta= event.getDelta(); if (delta != null) System.out.println("delta received: "); System.out.print(delta); IJavaElementDelta 包括已更改的元素和描述所发生的更改类型的标志。在大多数时候,delta 树的根位于“Java 模型”级别。然后,客户机必须使用 getAffectedChildren 来浏览此 delta 以了解已经更改

47、了哪些项目。以下示例方法遍历 delta,并打印已添加、已除去和已更改的元素: void traverseAndPrint(IJavaElementDelta delta) switch (delta.getKind() case IJavaElementDelta.ADDED: System.out.println(delta.getElement() + " was added"); break; case IJavaElementDelta.REMOVED: System.out.println(delta.getElement() + " was remo

48、ved"); break; case IJavaElementDelta.CHANGED: System.out.println(delta.getElement() + " was changed"); if (delta.getFlags() & IJavaElementDelta.F_CHILDREN) != 0) System.out.println("The change was in its children"); if (delta.getFlags() & IJavaElementDelta.F_CONTENT)

49、 != 0) System.out.println("The change was in its content"); /* Others flags can also be checked */ break; IJavaElementDelta children = delta.getAffectedChildren(); for (int i = 0; i < children.length; i+) traverseAndPrint(childreni); 有多种操作可以触发 Java 元素更改通知。以下是一些示例: · 创建资源,例如 IPackag

50、eFragment.createCompilationUnit(delta 指示编译单元的添加) · 修改资源,例如 ICompilationUnit.createType(delta 指示编译单元已更改,并且已添加类型来作为此编译单元的子代) · 修改项目的类路径,例如 IJavaProject.setRawClasspath(delta 指示包段根目录已添加至类路径、已从类路径中除去或在类路径上已重新排序) · 修改类路径变量值,例如 JavaCore.setClasspathVariable(delta 还指示包段根目录已经受到影响) · 更改 .

51、jar 文件的源代码连接,例如 IPackageFragmentRoot.attachSource(delta 指示源已拆离,然后连接) · 使工作副本与它的缓冲区协调,例如 IWorkingCopy.reconcile · 修改以“.java”结尾并且在项目的类路径上的 IFile,例如,使用 IFile.setContents(delta 指示编译单元已更改,但是未提供更详细的信息,原因是这不是通过“Java 模型”操作来完成的) 与 IResourceDelta 相似,可以使用 IWorkspaceRunnable 来对 Java 元素 delta 进行批处理。立即就

52、会合并和报告在 IWorkspaceRunnable 中运行的若干“Java 模型”操作产生的 delta。   JavaCore 提供了 run 方法来对 Java 元素更改进行批处理。例如,以下代码段将触发两个 Java 元素更改事件: / Get package IPackageFragment pkg = .; / Create 2 compilation units ICompilationUnit unitA = pkg.createCompilationUnit("A.java", "public class A ",

53、false, null); ICompilationUnit unitB = pkg.createCompilationUnit("B.java", "public class B ", false, null);而以下代码段将触发 1 个 Java 元素更改事件: / Get package IPackageFragment pkg = .; / Create 2 compilation units JavaCore.run( new IWorkspaceRunnable() public void run(IProgressMonitor monit

54、or) throws CoreException ICompilationUnit unitA = pkg.createCompilationUnit("A.java", "public class A ", false, null); ICompilationUnit unitB = pkg.createCompilationUnit("B.java", "public class B ", false, null); , null);设置 Java 构建路径本节描述如何设置 Java 构建路径。构建路径是用于构

55、建 Java 项目(IJavaProject)的类路径。类路径只是一组用于描述可用类型的类路径条目(IClassPathEntry)。类型能够以源或二进制格式出现,并且条目在路径中的顺序定义了用于在构建期间解析类型的查找顺序。Java 构建路径反映在 Java 项目元素的结构中。可以查询项目的包段根目录(IPackageFragmentRoot)。每个类路径条目都映射至一个或多个包段根目录,每个包段根目录进一步包含一组包段。此处对构建路径的讨论不涉及 Java 运行时路径,Java 运行时路径可以独立于构建路径进行定义。(有关运行时类路径的讨论,请参阅运行 Java 代码。)更改构建路径可以通过对相应项目的 Java 元素使用 setRawClasspath 来使用程序更改项目的构建路径。以下代码设置项目资源的类路径: IProject project = . / get some project resourceIJavaProject javaProjec

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论